From 4e51bc628c0cf61041267bc1bc0d6f41a592b056 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Tue, 15 Nov 2022 06:53:35 +0100 Subject: [PATCH 01/25] Fix incorrect value for `rollForward` in global.json --- global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global.json b/global.json index cb8c6c79d..2dc2bd474 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { "version": "6.0.403", - "rollForward": "latestFeature" + "rollForward": "latestMajor" } } From 9907d0bbd520945b4324bd2e246a51e9eb3ba110 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Tue, 15 Nov 2022 06:58:53 +0100 Subject: [PATCH 02/25] Restrict to "LatestMinor" --- global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global.json b/global.json index 2dc2bd474..afde5be54 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { "version": "6.0.403", - "rollForward": "latestMajor" + "rollForward": "latestMinor" } } From 93557978906e98fd2f720d6a022921b37272b82e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Tue, 15 Nov 2022 07:53:15 +0100 Subject: [PATCH 03/25] Only update version --- global.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/global.json b/global.json index afde5be54..77c776f82 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "6.0.403", - "rollForward": "latestMinor" + "version": "7.0.100", + "rollForward": "latestFeature" } } From fae87ee7dc6f52adb178acc540c6080c3b10270a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Tue, 15 Nov 2022 08:12:09 +0100 Subject: [PATCH 04/25] Re-Implement FileSystemExtensibility --- .../FileSystemExtensibility.cs | 34 ++++++++++++++ .../MockDirectoryInfo.cs | 4 ++ .../MockFileInfo.cs | 4 ++ .../MockFileStream.cs | 4 ++ .../DirectoryInfoWrapper.cs | 4 ++ .../FileInfoWrapper.cs | 4 ++ .../FileStreamWrapper.cs | 4 ++ .../FileSystemExtensibility.cs | 46 +++++++++++++++++++ .../FileSystemInfoBase.cs | 3 ++ .../FileSystemStream.cs | 5 ++ .../IFileSystemExtensibility.cs | 37 +++++++++++++++ .../IFileSystemInfo.cs | 5 ++ 12 files changed, 154 insertions(+) create mode 100644 src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs create mode 100644 src/TestableIO.System.IO.Abstractions.Wrappers/FileSystemExtensibility.cs create mode 100644 src/TestableIO.System.IO.Abstractions/IFileSystemExtensibility.cs diff --git a/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs b/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs new file mode 100644 index 000000000..4339cd672 --- /dev/null +++ b/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs @@ -0,0 +1,34 @@ +using System.Collections.Generic; + +namespace System.IO.Abstractions.TestingHelpers +{ + internal class FileSystemExtensibility : IFileSystemExtensibility + { + private readonly Dictionary _metadata = new(); + + /// + public bool TryGetWrappedInstance(out T wrappedInstance) + { + wrappedInstance = default; + return false; + } + + /// + public void StoreMetadata(string key, T value) + { + _metadata[key] = value; + } + + /// + public T RetrieveMetadata(string key) + { + if (_metadata.TryGetValue(key, out object value) && + value is T castedValue) + { + return castedValue; + } + + return default; + } + } +} \ No newline at end of file diff --git a/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs b/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs index c088c74a2..439e1ba8e 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs @@ -36,6 +36,7 @@ public MockDirectoryInfo(IMockFileDataAccessor mockFileDataAccessor, string dire } this.directoryPath = directoryPath; Refresh(); + this.Extensibility = new FileSystemExtensibility(); } #if FEATURE_CREATE_SYMBOLIC_LINK @@ -98,6 +99,9 @@ public override bool Exists } } + /// + public override IFileSystemExtensibility Extensibility { get; } + /// public override string Extension { diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs b/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs index 30df00439..afd19bd4c 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs @@ -22,6 +22,7 @@ public MockFileInfo(IMockFileDataAccessor mockFileSystem, string path) : base(mo this.path = mockFileSystem.Path.GetFullPath(path); this.mockFile = new MockFile(mockFileSystem); Refresh(); + this.Extensibility = new FileSystemExtensibility(); } #if FEATURE_CREATE_SYMBOLIC_LINK @@ -109,6 +110,9 @@ public override bool Exists } } + /// + public override IFileSystemExtensibility Extensibility { get; } + /// public override string Extension { diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFileStream.cs b/src/System.IO.Abstractions.TestingHelpers/MockFileStream.cs index 530b366ca..51a1f8656 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFileStream.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFileStream.cs @@ -26,6 +26,7 @@ public class MockFileStream : FileSystemStream (options & FileOptions.Asynchronous) != 0) { + this.Extensibility = new FileSystemExtensibility(); this.mockFileDataAccessor = mockFileDataAccessor ?? throw new ArgumentNullException(nameof(mockFileDataAccessor)); this.path = path; this.options = options; @@ -113,6 +114,9 @@ public override void EndWrite(IAsyncResult asyncResult) base.EndWrite(asyncResult); } + /// + public override IFileSystemExtensibility Extensibility { get; } + /// public override void SetLength(long value) { diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoWrapper.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoWrapper.cs index f5836f9cd..1c12ae028 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoWrapper.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoWrapper.cs @@ -15,6 +15,7 @@ public class DirectoryInfoWrapper : DirectoryInfoBase public DirectoryInfoWrapper(IFileSystem fileSystem, DirectoryInfo instance) : base(fileSystem) { this.instance = instance ?? throw new ArgumentNullException(nameof(instance)); + this.Extensibility = new FileSystemExtensibility(instance); } #if FEATURE_CREATE_SYMBOLIC_LINK @@ -72,6 +73,9 @@ public override bool Exists get { return instance.Exists; } } + /// + public override IFileSystemExtensibility Extensibility { get; } + /// public override string Extension { diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoWrapper.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoWrapper.cs index 177f82008..3f0d5fef4 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoWrapper.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoWrapper.cs @@ -13,6 +13,7 @@ public class FileInfoWrapper : FileInfoBase public FileInfoWrapper(IFileSystem fileSystem, FileInfo instance) : base(fileSystem) { this.instance = instance ?? throw new ArgumentNullException(nameof(instance)); + this.Extensibility = new FileSystemExtensibility(instance); } #if FEATURE_CREATE_SYMBOLIC_LINK @@ -70,6 +71,9 @@ public override bool Exists get { return instance.Exists; } } + /// + public override IFileSystemExtensibility Extensibility { get; } + /// public override string Extension { diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/FileStreamWrapper.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/FileStreamWrapper.cs index d21dc0456..c80a5eab7 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/FileStreamWrapper.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/FileStreamWrapper.cs @@ -6,6 +6,10 @@ public FileStreamWrapper(FileStream fileStream) : base(fileStream, fileStream.Name, fileStream.IsAsync) { + Extensibility = new FileSystemExtensibility(fileStream); } + + /// + public override IFileSystemExtensibility Extensibility { get; } } } \ No newline at end of file diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/FileSystemExtensibility.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/FileSystemExtensibility.cs new file mode 100644 index 000000000..01cc59996 --- /dev/null +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/FileSystemExtensibility.cs @@ -0,0 +1,46 @@ +using System.Collections.Generic; + +namespace System.IO.Abstractions +{ + internal class FileSystemExtensibility : IFileSystemExtensibility + { + private readonly object _wrappedInstance; + private readonly Dictionary _metadata = new(); + + public FileSystemExtensibility(object wrappedInstance) + { + _wrappedInstance = wrappedInstance; + } + + /// + public bool TryGetWrappedInstance(out T wrappedInstance) + { + if (_wrappedInstance is T value) + { + wrappedInstance = value; + return true; + } + + wrappedInstance = default; + return false; + } + + /// + public void StoreMetadata(string key, T value) + { + _metadata[key] = value; + } + + /// + public T RetrieveMetadata(string key) + { + if (_metadata.TryGetValue(key, out object value) && + value is T castedValue) + { + return castedValue; + } + + return default; + } + } +} \ No newline at end of file diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/FileSystemInfoBase.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/FileSystemInfoBase.cs index 7b265eb71..ce59dfc3c 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/FileSystemInfoBase.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/FileSystemInfoBase.cs @@ -46,6 +46,9 @@ protected FileSystemInfoBase(IFileSystem fileSystem) /// public abstract bool Exists { get; } + /// + public abstract IFileSystemExtensibility Extensibility { get; } + /// public abstract string Extension { get; } diff --git a/src/TestableIO.System.IO.Abstractions/FileSystemStream.cs b/src/TestableIO.System.IO.Abstractions/FileSystemStream.cs index 839986a75..becc41d65 100644 --- a/src/TestableIO.System.IO.Abstractions/FileSystemStream.cs +++ b/src/TestableIO.System.IO.Abstractions/FileSystemStream.cs @@ -24,6 +24,11 @@ public override bool CanTimeout public override bool CanWrite => _stream.CanWrite; + /// + /// A container to support extensions on. + /// + public abstract IFileSystemExtensibility Extensibility { get; } + /// public bool IsAsync { get; } diff --git a/src/TestableIO.System.IO.Abstractions/IFileSystemExtensibility.cs b/src/TestableIO.System.IO.Abstractions/IFileSystemExtensibility.cs new file mode 100644 index 000000000..72d59ee73 --- /dev/null +++ b/src/TestableIO.System.IO.Abstractions/IFileSystemExtensibility.cs @@ -0,0 +1,37 @@ +using System.Diagnostics.CodeAnalysis; + +namespace System.IO.Abstractions +{ + /// + /// A container to give access to the wrapped instance and to store metadata on entities. + ///
+ /// This is useful for writing extension methods. + ///
+ public interface IFileSystemExtensibility + { + /// + /// The wrapped instance on a real file system. + /// + /// + /// when not on a real file system or if the requested type does not match, + /// otherwise the wrapped instance. + /// + bool TryGetWrappedInstance([NotNullWhen(true)] out T? wrappedInstance); + + /// + /// Stores additional metadata to the . + /// + /// The type of the value to store. + /// The key under which to store the metadata. + /// The value to store under the given . + void StoreMetadata(string key, T? value); + + /// + /// Retrieves a previously stored metadata on the . + /// + /// The type of the value to retrieve. + /// The key under which the metadata was stored. + /// The value of the previously stored metadata, or . + T? RetrieveMetadata(string key); + } +} \ No newline at end of file diff --git a/src/TestableIO.System.IO.Abstractions/IFileSystemInfo.cs b/src/TestableIO.System.IO.Abstractions/IFileSystemInfo.cs index 68e6a25ee..b1208c26a 100644 --- a/src/TestableIO.System.IO.Abstractions/IFileSystemInfo.cs +++ b/src/TestableIO.System.IO.Abstractions/IFileSystemInfo.cs @@ -20,6 +20,11 @@ public interface IFileSystemInfo /// bool Exists { get; } + /// + /// A container to support extensions on . + /// + IFileSystemExtensibility Extensibility { get; } + /// string Extension { get; } From bc8360703a3e0d50084926dccb7735a0ea865e7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Tue, 15 Nov 2022 08:16:49 +0100 Subject: [PATCH 05/25] Remove ACL-Features from Interfaces --- .../IDirectory.cs | 31 +------------------ .../IDirectoryInfo.cs | 31 ------------------- .../IFile.cs | 25 --------------- .../IFileInfo.cs | 19 ------------ .../TestableIO.System.IO.Abstractions.csproj | 6 ---- 5 files changed, 1 insertion(+), 111 deletions(-) diff --git a/src/TestableIO.System.IO.Abstractions/IDirectory.cs b/src/TestableIO.System.IO.Abstractions/IDirectory.cs index dbe014245..63c62276c 100644 --- a/src/TestableIO.System.IO.Abstractions/IDirectory.cs +++ b/src/TestableIO.System.IO.Abstractions/IDirectory.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using System.Security.AccessControl; namespace System.IO.Abstractions { @@ -11,14 +10,7 @@ public interface IDirectory : IFileSystemEntity { /// IDirectoryInfo CreateDirectory(string path); - -#if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS - /// -#else - /// -#endif - IDirectoryInfo CreateDirectory(string path, DirectorySecurity directorySecurity); - + #if FEATURE_CREATE_SYMBOLIC_LINK /// IFileSystemInfo CreateSymbolicLink(string path, string pathToTarget); @@ -75,20 +67,6 @@ public interface IDirectory : IFileSystemEntity /// bool Exists([NotNullWhen(true)] string? path); -#if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS - /// -#else - /// -#endif - DirectorySecurity GetAccessControl(string path); - -#if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS - /// -#else - /// -#endif - DirectorySecurity GetAccessControl(string path, AccessControlSections includeSections); - /// DateTime GetCreationTime(string path); @@ -169,13 +147,6 @@ public interface IDirectory : IFileSystemEntity IFileSystemInfo? ResolveLinkTarget(string linkPath, bool returnFinalTarget); #endif -#if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS - /// -#else - /// -#endif - void SetAccessControl(string path, DirectorySecurity directorySecurity); - /// void SetCreationTime(string path, DateTime creationTime); diff --git a/src/TestableIO.System.IO.Abstractions/IDirectoryInfo.cs b/src/TestableIO.System.IO.Abstractions/IDirectoryInfo.cs index 1e19a036c..93fa0f2ab 100644 --- a/src/TestableIO.System.IO.Abstractions/IDirectoryInfo.cs +++ b/src/TestableIO.System.IO.Abstractions/IDirectoryInfo.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.Security.AccessControl; namespace System.IO.Abstractions { @@ -15,13 +14,6 @@ public interface IDirectoryInfo : IFileSystemInfo /// void Create(); -#if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS - /// -#else - /// -#endif - void Create(DirectorySecurity directorySecurity); - /// IDirectoryInfo CreateSubdirectory(string path); @@ -70,21 +62,6 @@ public interface IDirectoryInfo : IFileSystemInfo IEnumerable EnumerateFileSystemInfos(string searchPattern, EnumerationOptions enumerationOptions); #endif -#if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS - /// -#else - /// -#endif - DirectorySecurity GetAccessControl(); - -#if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS - /// -#else - /// -#endif - DirectorySecurity GetAccessControl(AccessControlSections includeSections); - - /// IDirectoryInfo[] GetDirectories(); @@ -129,13 +106,5 @@ public interface IDirectoryInfo : IFileSystemInfo /// void MoveTo(string destDirName); - - -#if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS - /// -#else - /// -#endif - void SetAccessControl(DirectorySecurity directorySecurity); } } \ No newline at end of file diff --git a/src/TestableIO.System.IO.Abstractions/IFile.cs b/src/TestableIO.System.IO.Abstractions/IFile.cs index f57d6967f..c640129e1 100644 --- a/src/TestableIO.System.IO.Abstractions/IFile.cs +++ b/src/TestableIO.System.IO.Abstractions/IFile.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Runtime.Versioning; -using System.Security.AccessControl; using System.Text; namespace System.IO.Abstractions @@ -66,22 +65,6 @@ public interface IFile : IFileSystemEntity /// bool Exists([NotNullWhen(true)] string? path); -#if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS - /// -#else - /// -#endif - [SupportedOSPlatform("windows")] - FileSecurity GetAccessControl(string path); - -#if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS - /// -#else - /// -#endif - [SupportedOSPlatform("windows")] - FileSecurity GetAccessControl(string path, AccessControlSections includeSections); - /// FileAttributes GetAttributes(string path); @@ -172,14 +155,6 @@ public interface IFile : IFileSystemEntity /// IFileSystemInfo? ResolveLinkTarget(string linkPath, bool returnFinalTarget); #endif - -#if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS - /// -#else - /// -#endif - [SupportedOSPlatform("windows")] - void SetAccessControl(string path, FileSecurity fileSecurity); /// void SetAttributes(string path, FileAttributes fileAttributes); diff --git a/src/TestableIO.System.IO.Abstractions/IFileInfo.cs b/src/TestableIO.System.IO.Abstractions/IFileInfo.cs index 556e51642..42e4cd5e6 100644 --- a/src/TestableIO.System.IO.Abstractions/IFileInfo.cs +++ b/src/TestableIO.System.IO.Abstractions/IFileInfo.cs @@ -1,5 +1,4 @@ using System.Runtime.Versioning; -using System.Security.AccessControl; namespace System.IO.Abstractions { @@ -41,19 +40,6 @@ public interface IFileInfo : IFileSystemInfo [SupportedOSPlatform("windows")] void Encrypt(); -#if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS - /// -#else - /// -#endif - FileSecurity GetAccessControl(); -#if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS - /// -#else - /// -#endif - FileSecurity GetAccessControl(AccessControlSections includeSections); - /// void MoveTo(string destFileName); @@ -93,10 +79,5 @@ public interface IFileInfo : IFileSystemInfo IFileInfo Replace(string destinationFileName, string? destinationBackupFileName, bool ignoreMetadataErrors); - -#if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS -#endif - /// - void SetAccessControl(FileSecurity fileSecurity); } } \ No newline at end of file diff --git a/src/TestableIO.System.IO.Abstractions/TestableIO.System.IO.Abstractions.csproj b/src/TestableIO.System.IO.Abstractions/TestableIO.System.IO.Abstractions.csproj index 3b2115b3f..28c7bb594 100644 --- a/src/TestableIO.System.IO.Abstractions/TestableIO.System.IO.Abstractions.csproj +++ b/src/TestableIO.System.IO.Abstractions/TestableIO.System.IO.Abstractions.csproj @@ -7,12 +7,6 @@ icon_256x256.png enable - - - - - - all From 27f4e620d6d34b14ebd609285b034a1af64862f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Tue, 15 Nov 2022 08:42:23 +0100 Subject: [PATCH 06/25] Replace implementation with ACL extension methods --- .../DirectoryAclExtensions.cs | 102 ++++++++++++++++++ .../DirectoryBase.cs | 20 +--- .../DirectoryInfoAclExtensions.cs | 91 ++++++++++++++++ .../DirectoryInfoBase.cs | 15 +-- .../DirectoryInfoWrapper.cs | 27 ----- .../DirectoryWrapper.cs | 29 ----- .../FileAclExtensions.cs | 73 +++++++++++++ .../FileBase.cs | 18 +--- .../FileInfoAclExtensions.cs | 68 ++++++++++++ .../FileInfoBase.cs | 13 +-- .../FileInfoWrapper.cs | 23 ---- .../FileStreamAclExtensions.cs | 49 +++++++++ .../FileWrapper.cs | 21 ---- 13 files changed, 392 insertions(+), 157 deletions(-) create mode 100644 src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryAclExtensions.cs create mode 100644 src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoAclExtensions.cs create mode 100644 src/TestableIO.System.IO.Abstractions.Wrappers/FileAclExtensions.cs create mode 100644 src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoAclExtensions.cs create mode 100644 src/TestableIO.System.IO.Abstractions.Wrappers/FileStreamAclExtensions.cs diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryAclExtensions.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryAclExtensions.cs new file mode 100644 index 000000000..62082a722 --- /dev/null +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryAclExtensions.cs @@ -0,0 +1,102 @@ +using System.Runtime.Versioning; +using System.Security.AccessControl; + +namespace System.IO.Abstractions +{ + /// + /// ACL (access control list) extension methods for . + /// + public static class DirectoryAclExtensions + { +#if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS + /// +#else + /// +#endif + [SupportedOSPlatform("windows")] + public static void CreateDirectory(this IDirectory directory, + string path, + DirectorySecurity directorySecurity) + { + IDirectoryInfo directoryInfo = + directory.FileSystem.DirectoryInfo.New(path); + IFileSystemExtensibility extensibility = + directoryInfo.Extensibility; + if (extensibility.TryGetWrappedInstance(out DirectoryInfo di)) + { + di.Create(directorySecurity); + } + else + { + extensibility.StoreMetadata("AccessControl", + directorySecurity); + directoryInfo.Create(); + } + } + +#if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS + /// +#else + /// +#endif + [SupportedOSPlatform("windows")] + public static DirectorySecurity GetAccessControl( + this IDirectory directory, string path) + { + IDirectoryInfo directoryInfo = + directory.FileSystem.DirectoryInfo.New(path); + IFileSystemExtensibility extensibility = + directoryInfo.Extensibility; + return extensibility.TryGetWrappedInstance(out DirectoryInfo di) + ? di.GetAccessControl() + : extensibility.RetrieveMetadata( + "AccessControl") ?? new DirectorySecurity(); + } + +#if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS + /// +#else + /// +#endif + [SupportedOSPlatform("windows")] + public static DirectorySecurity GetAccessControl( + this IDirectory directory, + string path, + AccessControlSections includeSections) + { + IDirectoryInfo directoryInfo = + directory.FileSystem.DirectoryInfo.New(path); + IFileSystemExtensibility extensibility = + directoryInfo.Extensibility; + return extensibility.TryGetWrappedInstance(out DirectoryInfo di) + ? di.GetAccessControl(includeSections) + : extensibility.RetrieveMetadata( + "AccessControl") ?? new DirectorySecurity(); + } + +#if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS + /// +#else + /// +#endif + [SupportedOSPlatform("windows")] + public static void SetAccessControl(this IDirectory directory, + string path, + DirectorySecurity directorySecurity) + { + IDirectoryInfo directoryInfo = + directory.FileSystem.DirectoryInfo.New(path); + IFileSystemExtensibility extensibility = + directoryInfo.Extensibility; + if (extensibility.TryGetWrappedInstance(out DirectoryInfo di)) + { + di.SetAccessControl(directorySecurity); + } + else + { + extensibility.StoreMetadata("AccessControl", + directorySecurity); + } + } + } +} \ No newline at end of file diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryBase.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryBase.cs index d7e8d1757..e5b5202da 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryBase.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryBase.cs @@ -24,10 +24,7 @@ protected DirectoryBase(IFileSystem fileSystem) /// public abstract IDirectoryInfo CreateDirectory(string path); - - /// - [SupportedOSPlatform("windows")] - public abstract IDirectoryInfo CreateDirectory(string path, DirectorySecurity directorySecurity); + #if FEATURE_CREATE_SYMBOLIC_LINK /// public abstract IFileSystemInfo CreateSymbolicLink(string path, string pathToTarget); @@ -40,15 +37,7 @@ protected DirectoryBase(IFileSystem fileSystem) /// public abstract bool Exists(string path); - - /// - [SupportedOSPlatform("windows")] - public abstract DirectorySecurity GetAccessControl(string path); - - /// - [SupportedOSPlatform("windows")] - public abstract DirectorySecurity GetAccessControl(string path, AccessControlSections includeSections); - + /// public abstract DateTime GetCreationTime(string path); @@ -129,10 +118,7 @@ protected DirectoryBase(IFileSystem fileSystem) /// public abstract IFileSystemInfo ResolveLinkTarget(string linkPath, bool returnFinalTarget); #endif - - /// - public abstract void SetAccessControl(string path, DirectorySecurity directorySecurity); - + /// public abstract void SetCreationTime(string path, DateTime creationTime); diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoAclExtensions.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoAclExtensions.cs new file mode 100644 index 000000000..e59e6fa0a --- /dev/null +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoAclExtensions.cs @@ -0,0 +1,91 @@ +using System.Runtime.Versioning; +using System.Security.AccessControl; + +namespace System.IO.Abstractions +{ + /// + /// ACL (access control list) extension methods for . + /// + public static class DirectoryInfoAclExtensions + { +#if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS + /// +#else + /// +#endif + [SupportedOSPlatform("windows")] + public static void Create(this IDirectoryInfo directoryInfo, + DirectorySecurity directorySecurity) + { + IFileSystemExtensibility extensibility = + directoryInfo.Extensibility; + if (extensibility.TryGetWrappedInstance(out DirectoryInfo di)) + { + di.Create(directorySecurity); + } + else + { + extensibility.StoreMetadata("AccessControl", + directorySecurity); + directoryInfo.Create(); + } + } + +#if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS + /// +#else + /// +#endif + [SupportedOSPlatform("windows")] + public static DirectorySecurity GetAccessControl( + this IDirectoryInfo directoryInfo) + { + IFileSystemExtensibility extensibility = + directoryInfo.Extensibility; + return extensibility.TryGetWrappedInstance(out DirectoryInfo di) + ? di.GetAccessControl() + : extensibility.RetrieveMetadata( + "AccessControl") ?? new DirectorySecurity(); + } + +#if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS + /// +#else + /// +#endif + [SupportedOSPlatform("windows")] + public static DirectorySecurity GetAccessControl( + this IDirectoryInfo directoryInfo, + AccessControlSections includeSections) + { + IFileSystemExtensibility extensibility = + directoryInfo.Extensibility; + return extensibility.TryGetWrappedInstance(out DirectoryInfo di) + ? di.GetAccessControl(includeSections) + : extensibility.RetrieveMetadata( + "AccessControl") ?? new DirectorySecurity(); + } + +#if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS + /// +#else + /// +#endif + [SupportedOSPlatform("windows")] + public static void SetAccessControl(this IDirectoryInfo directoryInfo, + DirectorySecurity directorySecurity) + { + IFileSystemExtensibility extensibility = + directoryInfo.Extensibility; + if (extensibility.TryGetWrappedInstance(out DirectoryInfo di)) + { + di.SetAccessControl(directorySecurity); + } + else + { + extensibility.StoreMetadata("AccessControl", + directorySecurity); + } + } + } +} \ No newline at end of file diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoBase.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoBase.cs index 49cf308ab..bbd12cd64 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoBase.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoBase.cs @@ -17,8 +17,6 @@ protected DirectoryInfoBase(IFileSystem fileSystem) : base(fileSystem) /// public abstract void Create(); - /// - public abstract void Create(DirectorySecurity directorySecurity); /// public abstract IDirectoryInfo CreateSubdirectory(string path); @@ -67,13 +65,7 @@ protected DirectoryInfoBase(IFileSystem fileSystem) : base(fileSystem) /// public abstract IEnumerable EnumerateFileSystemInfos(string searchPattern, EnumerationOptions enumerationOptions); #endif - - /// - public abstract DirectorySecurity GetAccessControl(); - - /// - public abstract DirectorySecurity GetAccessControl(AccessControlSections includeSections); - + /// public abstract IDirectoryInfo[] GetDirectories(); @@ -119,10 +111,7 @@ protected DirectoryInfoBase(IFileSystem fileSystem) : base(fileSystem) /// public abstract void MoveTo(string destDirName); - - /// - public abstract void SetAccessControl(DirectorySecurity directorySecurity); - + /// public abstract IDirectoryInfo Parent { get; } diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoWrapper.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoWrapper.cs index 1c12ae028..cb96e745e 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoWrapper.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoWrapper.cs @@ -136,13 +136,6 @@ public override void Create() instance.Create(); } - /// - [SupportedOSPlatform("windows")] - public override void Create(DirectorySecurity directorySecurity) - { - instance.Create(directorySecurity); - } - /// public override IDirectoryInfo CreateSubdirectory(string path) { @@ -232,19 +225,6 @@ public override IEnumerable EnumerateFileSystemInfos(string sea return instance.EnumerateFileSystemInfos(searchPattern, enumerationOptions).WrapFileSystemInfos(FileSystem); } #endif - /// - [SupportedOSPlatform("windows")] - public override DirectorySecurity GetAccessControl() - { - return instance.GetAccessControl(); - } - - /// - [SupportedOSPlatform("windows")] - public override DirectorySecurity GetAccessControl(AccessControlSections includeSections) - { - return instance.GetAccessControl(includeSections); - } /// public override IDirectoryInfo[] GetDirectories() @@ -330,13 +310,6 @@ public override void MoveTo(string destDirName) instance.MoveTo(destDirName); } - /// - [SupportedOSPlatform("windows")] - public override void SetAccessControl(DirectorySecurity directorySecurity) - { - instance.SetAccessControl(directorySecurity); - } - /// public override IDirectoryInfo Parent { diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryWrapper.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryWrapper.cs index 4db684b91..922ad659c 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryWrapper.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryWrapper.cs @@ -21,14 +21,6 @@ public override IDirectoryInfo CreateDirectory(string path) return new DirectoryInfoWrapper(FileSystem, directoryInfo); } - /// - [SupportedOSPlatform("windows")] - public override IDirectoryInfo CreateDirectory(string path, DirectorySecurity directorySecurity) - { - var directoryInfo = new DirectoryInfo(path); - directoryInfo.Create(directorySecurity); - return new DirectoryInfoWrapper(FileSystem, directoryInfo); - } #if FEATURE_CREATE_SYMBOLIC_LINK /// public override IFileSystemInfo CreateSymbolicLink(string path, string pathToTarget) @@ -54,20 +46,6 @@ public override bool Exists(string path) return Directory.Exists(path); } - /// - [SupportedOSPlatform("windows")] - public override DirectorySecurity GetAccessControl(string path) - { - return new DirectoryInfo(path).GetAccessControl(); - } - - /// - [SupportedOSPlatform("windows")] - public override DirectorySecurity GetAccessControl(string path, AccessControlSections includeSections) - { - return new DirectoryInfo(path).GetAccessControl(includeSections); - } - /// public override DateTime GetCreationTime(string path) { @@ -227,13 +205,6 @@ public override IFileSystemInfo ResolveLinkTarget(string linkPath, bool returnFi } #endif - /// - [SupportedOSPlatform("windows")] - public override void SetAccessControl(string path, DirectorySecurity directorySecurity) - { - new DirectoryInfo(path).SetAccessControl(directorySecurity); - } - /// public override void SetCreationTime(string path, DateTime creationTime) { diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/FileAclExtensions.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/FileAclExtensions.cs new file mode 100644 index 000000000..be5d1c544 --- /dev/null +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/FileAclExtensions.cs @@ -0,0 +1,73 @@ +using System.Runtime.Versioning; +using System.Security.AccessControl; + +namespace System.IO.Abstractions +{ + /// + /// ACL (access control list) extension methods for . + /// + public static class FileAclExtensions + { +#if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS + /// +#else + /// +#endif + [SupportedOSPlatform("windows")] + public static FileSecurity GetAccessControl( + this IFile file, string path) + { + IFileInfo fileInfo = file.FileSystem.FileInfo.New(path); + IFileSystemExtensibility extensibility = + fileInfo.Extensibility; + return extensibility.TryGetWrappedInstance(out FileInfo fi) + ? fi.GetAccessControl() + : extensibility.RetrieveMetadata( + "AccessControl") ?? new FileSecurity(); + } + +#if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS + /// +#else + /// +#endif + [SupportedOSPlatform("windows")] + public static FileSecurity GetAccessControl( + this IFile file, + string path, + AccessControlSections includeSections) + { + IFileInfo fileInfo = file.FileSystem.FileInfo.New(path); + IFileSystemExtensibility extensibility = + fileInfo.Extensibility; + return extensibility.TryGetWrappedInstance(out FileInfo fi) + ? fi.GetAccessControl(includeSections) + : extensibility.RetrieveMetadata( + "AccessControl") ?? new FileSecurity(); + } + +#if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS + /// +#else + /// +#endif + [SupportedOSPlatform("windows")] + public static void SetAccessControl(this IFile file, + string path, + FileSecurity fileSecurity) + { + IFileInfo fileInfo = file.FileSystem.FileInfo.New(path); + IFileSystemExtensibility extensibility = + fileInfo.Extensibility; + if (extensibility.TryGetWrappedInstance(out FileInfo fi)) + { + fi.SetAccessControl(fileSecurity); + } + else + { + extensibility.StoreMetadata("AccessControl", + fileSecurity); + } + } + } +} \ No newline at end of file diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/FileBase.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/FileBase.cs index eb19e490e..6375fa753 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/FileBase.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/FileBase.cs @@ -94,17 +94,7 @@ protected FileBase(IFileSystem fileSystem) /// /// public abstract bool Exists(string path); - - - /// - [SupportedOSPlatform("windows")] - public abstract FileSecurity GetAccessControl(string path); - - /// - [SupportedOSPlatform("windows")] - public abstract FileSecurity GetAccessControl(string path, AccessControlSections includeSections); - - + /// /// /// Gets the of the file on the path. @@ -329,11 +319,7 @@ protected FileBase(IFileSystem fileSystem) /// public abstract IFileSystemInfo ResolveLinkTarget(string linkPath, bool returnFinalTarget); #endif - - /// - [SupportedOSPlatform("windows")] - public abstract void SetAccessControl(string path, FileSecurity fileSecurity); - + /// public abstract void SetAttributes(string path, FileAttributes fileAttributes); diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoAclExtensions.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoAclExtensions.cs new file mode 100644 index 000000000..ddf310da1 --- /dev/null +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoAclExtensions.cs @@ -0,0 +1,68 @@ +using System.Runtime.Versioning; +using System.Security.AccessControl; + +namespace System.IO.Abstractions +{ + /// + /// ACL (access control list) extension methods for . + /// + public static class FileInfoAclExtensions + { +#if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS + /// +#else + /// +#endif + [SupportedOSPlatform("windows")] + public static FileSecurity GetAccessControl( + this IFileInfo fileInfo) + { + IFileSystemExtensibility extensibility = + fileInfo.Extensibility; + return extensibility.TryGetWrappedInstance(out FileInfo fi) + ? fi.GetAccessControl() + : extensibility.RetrieveMetadata( + "AccessControl") ?? new FileSecurity(); + } + +#if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS + /// +#else + /// +#endif + [SupportedOSPlatform("windows")] + public static FileSecurity GetAccessControl( + this IFileInfo fileInfo, + AccessControlSections includeSections) + { + IFileSystemExtensibility extensibility = + fileInfo.Extensibility; + return extensibility.TryGetWrappedInstance(out FileInfo fi) + ? fi.GetAccessControl(includeSections) + : extensibility.RetrieveMetadata( + "AccessControl") ?? new FileSecurity(); + } + +#if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS + /// +#else + /// +#endif + [SupportedOSPlatform("windows")] + public static void SetAccessControl(this IFileInfo fileInfo, + FileSecurity fileSecurity) + { + IFileSystemExtensibility extensibility = + fileInfo.Extensibility; + if (extensibility.TryGetWrappedInstance(out FileInfo fi)) + { + fi.SetAccessControl(fileSecurity); + } + else + { + extensibility.StoreMetadata("AccessControl", + fileSecurity); + } + } + } +} \ No newline at end of file diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoBase.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoBase.cs index b894a8e61..a0eb30c30 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoBase.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoBase.cs @@ -34,13 +34,7 @@ protected FileInfoBase(IFileSystem fileSystem) : base(fileSystem) /// public abstract void Encrypt(); - - /// - public abstract FileSecurity GetAccessControl(); - - /// - public abstract FileSecurity GetAccessControl(AccessControlSections includeSections); - + /// public abstract void MoveTo(string destFileName); @@ -77,10 +71,7 @@ protected FileInfoBase(IFileSystem fileSystem) : base(fileSystem) /// public abstract IFileInfo Replace(string destinationFileName, string destinationBackupFileName, bool ignoreMetadataErrors); - - /// - public abstract void SetAccessControl(FileSecurity fileSecurity); - + /// public abstract IDirectoryInfo Directory { get; } diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoWrapper.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoWrapper.cs index 3f0d5fef4..dbb3a230b 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoWrapper.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoWrapper.cs @@ -172,22 +172,6 @@ public override void Encrypt() instance.Encrypt(); } - /// - - [SupportedOSPlatform("windows")] - public override FileSecurity GetAccessControl() - { - return instance.GetAccessControl(); - } - - /// - - [SupportedOSPlatform("windows")] - public override FileSecurity GetAccessControl(AccessControlSections includeSections) - { - return instance.GetAccessControl(includeSections); - } - /// public override void MoveTo(string destFileName) { @@ -258,13 +242,6 @@ public override IFileInfo Replace(string destinationFileName, string destination return new FileInfoWrapper(FileSystem, instance.Replace(destinationFileName, destinationBackupFileName, ignoreMetadataErrors)); } - /// - [SupportedOSPlatform("windows")] - public override void SetAccessControl(FileSecurity fileSecurity) - { - instance.SetAccessControl(fileSecurity); - } - /// public override IDirectoryInfo Directory { diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/FileStreamAclExtensions.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/FileStreamAclExtensions.cs new file mode 100644 index 000000000..be4551344 --- /dev/null +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/FileStreamAclExtensions.cs @@ -0,0 +1,49 @@ +using System.Runtime.Versioning; +using System.Security.AccessControl; + +namespace System.IO.Abstractions +{ + /// + /// ACL (access control list) extension methods for . + /// + public static class FileStreamAclExtensions + { +#if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS + /// +#else + /// +#endif + [SupportedOSPlatform("windows")] + public static FileSecurity GetAccessControl(this FileSystemStream fileStream) + { + IFileSystemExtensibility extensibility = + fileStream.Extensibility; + return extensibility.TryGetWrappedInstance(out FileStream fs) + ? fs.GetAccessControl() + : extensibility.RetrieveMetadata( + "AccessControl") ?? new FileSecurity(); + } + +#if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS + /// +#else + /// +#endif + [SupportedOSPlatform("windows")] + public static void SetAccessControl(this FileSystemStream fileStream, + FileSecurity fileSecurity) + { + IFileSystemExtensibility extensibility = + fileStream.Extensibility; + if (extensibility.TryGetWrappedInstance(out FileStream fs)) + { + fs.SetAccessControl(fileSecurity); + } + else + { + extensibility.StoreMetadata("AccessControl", + fileSecurity); + } + } + } +} \ No newline at end of file diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/FileWrapper.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/FileWrapper.cs index 6e067d493..1dc42e022 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/FileWrapper.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/FileWrapper.cs @@ -114,20 +114,6 @@ public override bool Exists(string path) return File.Exists(path); } - /// - [SupportedOSPlatform("windows")] - public override FileSecurity GetAccessControl(string path) - { - return new FileInfo(path).GetAccessControl(); - } - - /// - [SupportedOSPlatform("windows")] - public override FileSecurity GetAccessControl(string path, AccessControlSections includeSections) - { - return new FileInfo(path).GetAccessControl(includeSections); - } - /// public override FileAttributes GetAttributes(string path) { @@ -291,13 +277,6 @@ public override IFileSystemInfo ResolveLinkTarget(string linkPath, bool returnFi } #endif - /// - [SupportedOSPlatform("windows")] - public override void SetAccessControl(string path, FileSecurity fileSecurity) - { - new FileInfo(path).SetAccessControl(fileSecurity); - } - /// public override void SetAttributes(string path, FileAttributes fileAttributes) { From d160c5dfa98dc34f52415992fd7a214e70bc492a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Tue, 15 Nov 2022 09:06:32 +0100 Subject: [PATCH 07/25] Adjust implementation in TestingHelpers --- .../MockDirectory.cs | 60 +------------------ .../MockDirectoryData.cs | 15 +++-- .../MockDirectoryInfo.cs | 35 ++--------- .../MockFile.cs | 40 ------------- .../MockFileData.cs | 23 ++++--- .../MockFileInfo.cs | 29 ++------- 6 files changed, 36 insertions(+), 166 deletions(-) diff --git a/src/System.IO.Abstractions.TestingHelpers/MockDirectory.cs b/src/System.IO.Abstractions.TestingHelpers/MockDirectory.cs index 6953539c5..6a81caa88 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockDirectory.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockDirectory.cs @@ -1,9 +1,6 @@ using System.Collections.Generic; -using System.ComponentModel; using System.Globalization; using System.Linq; -using System.Runtime.Versioning; -using System.Security.AccessControl; using System.Text.RegularExpressions; namespace System.IO.Abstractions.TestingHelpers @@ -39,17 +36,10 @@ public class MockDirectory : DirectoryBase /// public override IDirectoryInfo CreateDirectory(string path) { - return CreateDirectoryInternal(path, null); + return CreateDirectoryInternal(path); } - - /// - public override IDirectoryInfo CreateDirectory(string path, DirectorySecurity directorySecurity) - { - return CreateDirectoryInternal(path, directorySecurity); - } - - private IDirectoryInfo CreateDirectoryInternal(string path, DirectorySecurity directorySecurity) + private IDirectoryInfo CreateDirectoryInternal(string path) { if (path == null) { @@ -80,11 +70,6 @@ private IDirectoryInfo CreateDirectoryInternal(string path, DirectorySecurity di var created = new MockDirectoryInfo(mockFileDataAccessor, path); - if (directorySecurity != null) - { - created.SetAccessControl(directorySecurity); - } - return created; } @@ -173,31 +158,6 @@ public override bool Exists(string path) } - /// - [SupportedOSPlatform("windows")] - public override DirectorySecurity GetAccessControl(string path) - { - mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(path, "path"); - path = path.TrimSlashes(); - - if (!mockFileDataAccessor.Directory.Exists(path)) - { - throw CommonExceptions.CouldNotFindPartOfPath(path); - } - - var directoryData = (MockDirectoryData)mockFileDataAccessor.GetFile(path); - return directoryData.AccessControl; - } - - - /// - [SupportedOSPlatform("windows")] - public override DirectorySecurity GetAccessControl(string path, AccessControlSections includeSections) - { - return GetAccessControl(path); - } - - /// public override DateTime GetCreationTime(string path) { @@ -559,22 +519,6 @@ public override IFileSystemInfo ResolveLinkTarget(string linkPath, bool returnFi #endif - /// - [SupportedOSPlatform("windows")] - public override void SetAccessControl(string path, DirectorySecurity directorySecurity) - { - mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(path, "path"); - path = path.TrimSlashes(); - - if (!mockFileDataAccessor.Directory.Exists(path)) - { - throw CommonExceptions.CouldNotFindPartOfPath(path); - } - - var directoryData = (MockDirectoryData)mockFileDataAccessor.GetFile(path); - directoryData.AccessControl = directorySecurity; - } - /// public override void SetCreationTime(string path, DateTime creationTime) { diff --git a/src/System.IO.Abstractions.TestingHelpers/MockDirectoryData.cs b/src/System.IO.Abstractions.TestingHelpers/MockDirectoryData.cs index 28d8925f1..d107f3419 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockDirectoryData.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockDirectoryData.cs @@ -7,10 +7,6 @@ namespace System.IO.Abstractions.TestingHelpers [Serializable] public class MockDirectoryData : MockFileData { - - [NonSerialized] - private DirectorySecurity accessControl; - /// public MockDirectoryData() : base(string.Empty) { @@ -25,9 +21,16 @@ public new DirectorySecurity AccessControl { // DirectorySecurity's constructor will throw PlatformNotSupportedException on non-Windows platform, so we initialize it in lazy way. // This let's us use this class as long as we don't use AccessControl property. - return accessControl ?? (accessControl = new DirectorySecurity()); + var directorySecurity = Extensibility.RetrieveMetadata("AccessControl"); + if (directorySecurity == null) + { + directorySecurity = new DirectorySecurity(); + Extensibility.StoreMetadata("AccessControl", directorySecurity); + } + + return directorySecurity; } - set { accessControl = value; } + set { Extensibility.StoreMetadata("AccessControl", value); } } } } \ No newline at end of file diff --git a/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs b/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs index 439e1ba8e..7822bbfe3 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs @@ -36,7 +36,6 @@ public MockDirectoryInfo(IMockFileDataAccessor mockFileDataAccessor, string dire } this.directoryPath = directoryPath; Refresh(); - this.Extensibility = new FileSystemExtensibility(); } #if FEATURE_CREATE_SYMBOLIC_LINK @@ -100,7 +99,8 @@ public override bool Exists } /// - public override IFileSystemExtensibility Extensibility { get; } + public override IFileSystemExtensibility Extensibility + => (mockFileDataAccessor.GetFile(directoryPath) ?? MockFileData.NullObject)?.Extensibility; /// public override string Extension @@ -183,14 +183,7 @@ public override void Create() mockFileDataAccessor.Directory.CreateDirectory(FullName); refreshOnNextRead = true; } - - /// - public override void Create(DirectorySecurity directorySecurity) - { - mockFileDataAccessor.Directory.CreateDirectory(FullName, directorySecurity); - refreshOnNextRead = true; - } - + /// public override IDirectoryInfo CreateSubdirectory(string path) { @@ -281,19 +274,7 @@ public override IEnumerable EnumerateFileSystemInfos(string sea return GetFileSystemInfos(searchPattern, enumerationOptions); } #endif - - /// - public override DirectorySecurity GetAccessControl() - { - return mockFileDataAccessor.Directory.GetAccessControl(directoryPath); - } - - /// - public override DirectorySecurity GetAccessControl(AccessControlSections includeSections) - { - return mockFileDataAccessor.Directory.GetAccessControl(directoryPath, includeSections); - } - + /// public override IDirectoryInfo[] GetDirectories() { @@ -392,13 +373,7 @@ public override void MoveTo(string destDirName) { mockFileDataAccessor.Directory.Move(directoryPath, destDirName); } - - /// - public override void SetAccessControl(DirectorySecurity directorySecurity) - { - mockFileDataAccessor.Directory.SetAccessControl(directoryPath, directorySecurity); - } - + /// public override IDirectoryInfo Parent { diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFile.cs b/src/System.IO.Abstractions.TestingHelpers/MockFile.cs index becca2430..17efc120a 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFile.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFile.cs @@ -1,8 +1,6 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; -using System.Runtime.Versioning; -using System.Security.AccessControl; using System.Text; namespace System.IO.Abstractions.TestingHelpers @@ -268,28 +266,6 @@ public override bool Exists(string path) return false; } - /// - [SupportedOSPlatform("windows")] - public override FileSecurity GetAccessControl(string path) - { - mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(path, "path"); - - if (!mockFileDataAccessor.FileExists(path)) - { - throw CommonExceptions.FileNotFound(path); - } - - var fileData = mockFileDataAccessor.GetFile(path); - return fileData.AccessControl; - } - - /// - [SupportedOSPlatform("windows")] - public override FileSecurity GetAccessControl(string path, AccessControlSections includeSections) - { - return GetAccessControl(path); - } - /// /// Gets the of the file on the path. /// @@ -732,22 +708,6 @@ public override IFileSystemInfo ResolveLinkTarget(string linkPath, bool returnFi } #endif - /// - [SupportedOSPlatform("windows")] - public override void SetAccessControl(string path, FileSecurity fileSecurity) - { - mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(path, "path"); - - if (!mockFileDataAccessor.FileExists(path)) - { - throw CommonExceptions.FileNotFound(path); - } - - var fileData = mockFileDataAccessor.GetFile(path); - mockFileDataAccessor.AdjustTimes(fileData, TimeAdjustments.LastAccessTime); - fileData.AccessControl = fileSecurity; - } - /// public override void SetAttributes(string path, FileAttributes fileAttributes) { diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs b/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs index 1c59dba63..350c874be 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs @@ -34,10 +34,10 @@ public class MockFileData public static readonly DateTimeOffset DefaultDateTimeOffset = new DateTime(1601, 01, 01, 00, 00, 00, DateTimeKind.Utc); /// - /// The access control of the . + /// The extensibility of the . /// - [NonSerialized] - private FileSecurity accessControl; + public IFileSystemExtensibility Extensibility { get; } + = new FileSystemExtensibility(); /// /// Gets a value indicating whether the is a directory or not. @@ -99,7 +99,9 @@ public MockFileData(MockFileData template) throw new ArgumentNullException(nameof(template)); } - accessControl = template.accessControl; +#pragma warning disable CA1416 + AccessControl = template.AccessControl; +#pragma warning restore CA1416 Attributes = template.Attributes; Contents = template.Contents.ToArray(); CreationTime = template.CreationTime; @@ -179,7 +181,7 @@ public DateTimeOffset LastWriteTime public FileAttributes Attributes { get; set; } = FileAttributes.Normal; /// - /// Gets or sets of the . This is the object that is returned for this when calling . + /// Gets or sets of the . /// [SupportedOSPlatform("windows")] public FileSecurity AccessControl @@ -188,9 +190,16 @@ public FileSecurity AccessControl { // FileSecurity's constructor will throw PlatformNotSupportedException on non-Windows platform, so we initialize it in lazy way. // This let's us use this class as long as we don't use AccessControl property. - return accessControl ?? (accessControl = new FileSecurity()); + var fileSecurity = Extensibility.RetrieveMetadata("AccessControl"); + if (fileSecurity == null) + { + fileSecurity = new FileSecurity(); + Extensibility.StoreMetadata("AccessControl", fileSecurity); + } + + return fileSecurity; } - set { accessControl = value; } + set { Extensibility.StoreMetadata("AccessControl", value); } } /// diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs b/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs index afd19bd4c..66595283a 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs @@ -22,7 +22,6 @@ public MockFileInfo(IMockFileDataAccessor mockFileSystem, string path) : base(mo this.path = mockFileSystem.Path.GetFullPath(path); this.mockFile = new MockFile(mockFileSystem); Refresh(); - this.Extensibility = new FileSystemExtensibility(); } #if FEATURE_CREATE_SYMBOLIC_LINK @@ -111,7 +110,8 @@ public override bool Exists } /// - public override IFileSystemExtensibility Extensibility { get; } + public override IFileSystemExtensibility Extensibility + => (mockFileSystem.GetFile(path) ?? MockFileData.NullObject)?.Extensibility; /// public override string Extension @@ -260,21 +260,7 @@ public override void Encrypt() var mockFileData = GetMockFileDataForWrite(); mockFileData.Attributes |= FileAttributes.Encrypted; } - - /// - [SupportedOSPlatform("windows")] - public override FileSecurity GetAccessControl() - { - return mockFileSystem.File.GetAccessControl(this.path); - } - - /// - [SupportedOSPlatform("windows")] - public override FileSecurity GetAccessControl(AccessControlSections includeSections) - { - return mockFileSystem.File.GetAccessControl(this.path, includeSections); - } - + /// public override void MoveTo(string destFileName) { @@ -338,14 +324,7 @@ public override IFileInfo Replace(string destinationFileName, string destination mockFile.Replace(path, destinationFileName, destinationBackupFileName, ignoreMetadataErrors); return mockFileSystem.FileInfo.New(destinationFileName); } - - /// - [SupportedOSPlatform("windows")] - public override void SetAccessControl(FileSecurity fileSecurity) - { - mockFile.SetAccessControl(this.path, fileSecurity); - } - + /// public override IDirectoryInfo Directory { From 33089c821883991dd1890f7943657a387d68b42b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Tue, 15 Nov 2022 09:12:09 +0100 Subject: [PATCH 08/25] Adjust Parity-Tests --- .../ApiParityTests.DirectoryInfo_.NET 5.0.snap | 6 ++---- .../ApiParityTests.DirectoryInfo_.NET 6.0.snap | 6 ++---- .../ApiParityTests.DirectoryInfo_.NET Core 3.1.snap | 6 ++---- ...arityTests.DirectoryInfo_.NET Framework 4.6.1.snap | 11 +++++++++-- .../ApiParityTests.Directory_.NET 5.0.snap | 7 +------ .../ApiParityTests.Directory_.NET 6.0.snap | 7 +------ .../ApiParityTests.Directory_.NET Core 3.1.snap | 7 +------ ...ApiParityTests.Directory_.NET Framework 4.6.1.snap | 7 ++++++- .../ApiParityTests.FileInfo_.NET 5.0.snap | 5 ++--- .../ApiParityTests.FileInfo_.NET 6.0.snap | 5 ++--- .../ApiParityTests.FileInfo_.NET Core 3.1.snap | 5 ++--- .../ApiParityTests.FileInfo_.NET Framework 4.6.1.snap | 10 ++++++++-- .../__snapshots__/ApiParityTests.File_.NET 5.0.snap | 6 +----- .../__snapshots__/ApiParityTests.File_.NET 6.0.snap | 6 +----- .../ApiParityTests.File_.NET Core 3.1.snap | 6 +----- .../ApiParityTests.File_.NET Framework 4.6.1.snap | 5 ++++- 16 files changed, 45 insertions(+), 60 deletions(-) diff --git a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.DirectoryInfo_.NET 5.0.snap b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.DirectoryInfo_.NET 5.0.snap index a7e18d8c3..e88780a62 100644 --- a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.DirectoryInfo_.NET 5.0.snap +++ b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.DirectoryInfo_.NET 5.0.snap @@ -1,9 +1,7 @@ { "ExtraMembers": [ - "System.Security.AccessControl.DirectorySecurity GetAccessControl()", - "System.Security.AccessControl.DirectorySecurity GetAccessControl(System.Security.AccessControl.AccessControlSections)", - "Void Create(System.Security.AccessControl.DirectorySecurity)", - "Void SetAccessControl(System.Security.AccessControl.DirectorySecurity)" + "System.IO.Abstractions.IFileSystemExtensibility Extensibility", + "System.IO.Abstractions.IFileSystemExtensibility get_Extensibility()" ], "MissingMembers": [ "System.Object GetLifetimeService()", diff --git a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.DirectoryInfo_.NET 6.0.snap b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.DirectoryInfo_.NET 6.0.snap index a7e18d8c3..e88780a62 100644 --- a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.DirectoryInfo_.NET 6.0.snap +++ b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.DirectoryInfo_.NET 6.0.snap @@ -1,9 +1,7 @@ { "ExtraMembers": [ - "System.Security.AccessControl.DirectorySecurity GetAccessControl()", - "System.Security.AccessControl.DirectorySecurity GetAccessControl(System.Security.AccessControl.AccessControlSections)", - "Void Create(System.Security.AccessControl.DirectorySecurity)", - "Void SetAccessControl(System.Security.AccessControl.DirectorySecurity)" + "System.IO.Abstractions.IFileSystemExtensibility Extensibility", + "System.IO.Abstractions.IFileSystemExtensibility get_Extensibility()" ], "MissingMembers": [ "System.Object GetLifetimeService()", diff --git a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.DirectoryInfo_.NET Core 3.1.snap b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.DirectoryInfo_.NET Core 3.1.snap index a7e18d8c3..e88780a62 100644 --- a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.DirectoryInfo_.NET Core 3.1.snap +++ b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.DirectoryInfo_.NET Core 3.1.snap @@ -1,9 +1,7 @@ { "ExtraMembers": [ - "System.Security.AccessControl.DirectorySecurity GetAccessControl()", - "System.Security.AccessControl.DirectorySecurity GetAccessControl(System.Security.AccessControl.AccessControlSections)", - "Void Create(System.Security.AccessControl.DirectorySecurity)", - "Void SetAccessControl(System.Security.AccessControl.DirectorySecurity)" + "System.IO.Abstractions.IFileSystemExtensibility Extensibility", + "System.IO.Abstractions.IFileSystemExtensibility get_Extensibility()" ], "MissingMembers": [ "System.Object GetLifetimeService()", diff --git a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.DirectoryInfo_.NET Framework 4.6.1.snap b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.DirectoryInfo_.NET Framework 4.6.1.snap index 9bf30cdc0..ee92992d2 100644 --- a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.DirectoryInfo_.NET Framework 4.6.1.snap +++ b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.DirectoryInfo_.NET Framework 4.6.1.snap @@ -1,11 +1,18 @@ { - "ExtraMembers": [], + "ExtraMembers": [ + "System.IO.Abstractions.IFileSystemExtensibility Extensibility", + "System.IO.Abstractions.IFileSystemExtensibility get_Extensibility()" + ], "MissingMembers": [ "System.IO.Abstractions.IDirectoryInfo CreateSubdirectory(System.String, System.Security.AccessControl.DirectorySecurity)", "System.Object GetLifetimeService()", "System.Object InitializeLifetimeService()", "System.Runtime.Remoting.ObjRef CreateObjRef(System.Type)", + "System.Security.AccessControl.DirectorySecurity GetAccessControl()", + "System.Security.AccessControl.DirectorySecurity GetAccessControl(System.Security.AccessControl.AccessControlSections)", "Void .ctor(System.String)", - "Void GetObjectData(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)" + "Void Create(System.Security.AccessControl.DirectorySecurity)", + "Void GetObjectData(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)", + "Void SetAccessControl(System.Security.AccessControl.DirectorySecurity)" ] } diff --git a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.Directory_.NET 5.0.snap b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.Directory_.NET 5.0.snap index 73b36d469..7cb3b9523 100644 --- a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.Directory_.NET 5.0.snap +++ b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.Directory_.NET 5.0.snap @@ -1,9 +1,4 @@ { - "ExtraMembers": [ - "System.IO.Abstractions.IDirectoryInfo CreateDirectory(System.String, System.Security.AccessControl.DirectorySecurity)", - "System.Security.AccessControl.DirectorySecurity GetAccessControl(System.String)", - "System.Security.AccessControl.DirectorySecurity GetAccessControl(System.String, System.Security.AccessControl.AccessControlSections)", - "Void SetAccessControl(System.String, System.Security.AccessControl.DirectorySecurity)" - ], + "ExtraMembers": [], "MissingMembers": [] } diff --git a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.Directory_.NET 6.0.snap b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.Directory_.NET 6.0.snap index 73b36d469..7cb3b9523 100644 --- a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.Directory_.NET 6.0.snap +++ b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.Directory_.NET 6.0.snap @@ -1,9 +1,4 @@ { - "ExtraMembers": [ - "System.IO.Abstractions.IDirectoryInfo CreateDirectory(System.String, System.Security.AccessControl.DirectorySecurity)", - "System.Security.AccessControl.DirectorySecurity GetAccessControl(System.String)", - "System.Security.AccessControl.DirectorySecurity GetAccessControl(System.String, System.Security.AccessControl.AccessControlSections)", - "Void SetAccessControl(System.String, System.Security.AccessControl.DirectorySecurity)" - ], + "ExtraMembers": [], "MissingMembers": [] } diff --git a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.Directory_.NET Core 3.1.snap b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.Directory_.NET Core 3.1.snap index 73b36d469..7cb3b9523 100644 --- a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.Directory_.NET Core 3.1.snap +++ b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.Directory_.NET Core 3.1.snap @@ -1,9 +1,4 @@ { - "ExtraMembers": [ - "System.IO.Abstractions.IDirectoryInfo CreateDirectory(System.String, System.Security.AccessControl.DirectorySecurity)", - "System.Security.AccessControl.DirectorySecurity GetAccessControl(System.String)", - "System.Security.AccessControl.DirectorySecurity GetAccessControl(System.String, System.Security.AccessControl.AccessControlSections)", - "Void SetAccessControl(System.String, System.Security.AccessControl.DirectorySecurity)" - ], + "ExtraMembers": [], "MissingMembers": [] } diff --git a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.Directory_.NET Framework 4.6.1.snap b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.Directory_.NET Framework 4.6.1.snap index 7cb3b9523..517bd1d06 100644 --- a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.Directory_.NET Framework 4.6.1.snap +++ b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.Directory_.NET Framework 4.6.1.snap @@ -1,4 +1,9 @@ { "ExtraMembers": [], - "MissingMembers": [] + "MissingMembers": [ + "System.IO.Abstractions.IDirectoryInfo CreateDirectory(System.String, System.Security.AccessControl.DirectorySecurity)", + "System.Security.AccessControl.DirectorySecurity GetAccessControl(System.String)", + "System.Security.AccessControl.DirectorySecurity GetAccessControl(System.String, System.Security.AccessControl.AccessControlSections)", + "Void SetAccessControl(System.String, System.Security.AccessControl.DirectorySecurity)" + ] } diff --git a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.FileInfo_.NET 5.0.snap b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.FileInfo_.NET 5.0.snap index e2e2adfd7..e88780a62 100644 --- a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.FileInfo_.NET 5.0.snap +++ b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.FileInfo_.NET 5.0.snap @@ -1,8 +1,7 @@ { "ExtraMembers": [ - "System.Security.AccessControl.FileSecurity GetAccessControl()", - "System.Security.AccessControl.FileSecurity GetAccessControl(System.Security.AccessControl.AccessControlSections)", - "Void SetAccessControl(System.Security.AccessControl.FileSecurity)" + "System.IO.Abstractions.IFileSystemExtensibility Extensibility", + "System.IO.Abstractions.IFileSystemExtensibility get_Extensibility()" ], "MissingMembers": [ "System.Object GetLifetimeService()", diff --git a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.FileInfo_.NET 6.0.snap b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.FileInfo_.NET 6.0.snap index e2e2adfd7..e88780a62 100644 --- a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.FileInfo_.NET 6.0.snap +++ b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.FileInfo_.NET 6.0.snap @@ -1,8 +1,7 @@ { "ExtraMembers": [ - "System.Security.AccessControl.FileSecurity GetAccessControl()", - "System.Security.AccessControl.FileSecurity GetAccessControl(System.Security.AccessControl.AccessControlSections)", - "Void SetAccessControl(System.Security.AccessControl.FileSecurity)" + "System.IO.Abstractions.IFileSystemExtensibility Extensibility", + "System.IO.Abstractions.IFileSystemExtensibility get_Extensibility()" ], "MissingMembers": [ "System.Object GetLifetimeService()", diff --git a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.FileInfo_.NET Core 3.1.snap b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.FileInfo_.NET Core 3.1.snap index ae8e3379d..816ad5ef5 100644 --- a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.FileInfo_.NET Core 3.1.snap +++ b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.FileInfo_.NET Core 3.1.snap @@ -1,8 +1,7 @@ { "ExtraMembers": [ - "System.Security.AccessControl.FileSecurity GetAccessControl()", - "System.Security.AccessControl.FileSecurity GetAccessControl(System.Security.AccessControl.AccessControlSections)", - "Void SetAccessControl(System.Security.AccessControl.FileSecurity)" + "System.IO.Abstractions.IFileSystemExtensibility Extensibility", + "System.IO.Abstractions.IFileSystemExtensibility get_Extensibility()" ], "MissingMembers": [ "System.Object GetLifetimeService()", diff --git a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.FileInfo_.NET Framework 4.6.1.snap b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.FileInfo_.NET Framework 4.6.1.snap index a4ae16c13..3fd5a58e5 100644 --- a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.FileInfo_.NET Framework 4.6.1.snap +++ b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.FileInfo_.NET Framework 4.6.1.snap @@ -1,10 +1,16 @@ { - "ExtraMembers": [], + "ExtraMembers": [ + "System.IO.Abstractions.IFileSystemExtensibility Extensibility", + "System.IO.Abstractions.IFileSystemExtensibility get_Extensibility()" + ], "MissingMembers": [ "System.Object GetLifetimeService()", "System.Object InitializeLifetimeService()", "System.Runtime.Remoting.ObjRef CreateObjRef(System.Type)", + "System.Security.AccessControl.FileSecurity GetAccessControl()", + "System.Security.AccessControl.FileSecurity GetAccessControl(System.Security.AccessControl.AccessControlSections)", "Void .ctor(System.String)", - "Void GetObjectData(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)" + "Void GetObjectData(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)", + "Void SetAccessControl(System.Security.AccessControl.FileSecurity)" ] } diff --git a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.File_.NET 5.0.snap b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.File_.NET 5.0.snap index d4303a9da..7cb3b9523 100644 --- a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.File_.NET 5.0.snap +++ b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.File_.NET 5.0.snap @@ -1,8 +1,4 @@ { - "ExtraMembers": [ - "System.Security.AccessControl.FileSecurity GetAccessControl(System.String)", - "System.Security.AccessControl.FileSecurity GetAccessControl(System.String, System.Security.AccessControl.AccessControlSections)", - "Void SetAccessControl(System.String, System.Security.AccessControl.FileSecurity)" - ], + "ExtraMembers": [], "MissingMembers": [] } diff --git a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.File_.NET 6.0.snap b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.File_.NET 6.0.snap index 22f84eff1..ce42363ab 100644 --- a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.File_.NET 6.0.snap +++ b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.File_.NET 6.0.snap @@ -1,9 +1,5 @@ { - "ExtraMembers": [ - "System.Security.AccessControl.FileSecurity GetAccessControl(System.String)", - "System.Security.AccessControl.FileSecurity GetAccessControl(System.String, System.Security.AccessControl.AccessControlSections)", - "Void SetAccessControl(System.String, System.Security.AccessControl.FileSecurity)" - ], + "ExtraMembers": [], "MissingMembers": [ "Microsoft.Win32.SafeHandles.SafeFileHandle OpenHandle(System.String, System.IO.FileMode, System.IO.FileAccess, System.IO.FileShare, System.IO.FileOptions, Int64)" ] diff --git a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.File_.NET Core 3.1.snap b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.File_.NET Core 3.1.snap index 58a209431..a72f89d15 100644 --- a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.File_.NET Core 3.1.snap +++ b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.File_.NET Core 3.1.snap @@ -1,9 +1,5 @@ { - "ExtraMembers": [ - "System.Security.AccessControl.FileSecurity GetAccessControl(System.String)", - "System.Security.AccessControl.FileSecurity GetAccessControl(System.String, System.Security.AccessControl.AccessControlSections)", - "Void SetAccessControl(System.String, System.Security.AccessControl.FileSecurity)" - ], + "ExtraMembers": [], "MissingMembers": [ "Void Move(System.String, System.String, Boolean)" ] diff --git a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.File_.NET Framework 4.6.1.snap b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.File_.NET Framework 4.6.1.snap index ad5f2cca9..2e2ed8e14 100644 --- a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.File_.NET Framework 4.6.1.snap +++ b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.File_.NET Framework 4.6.1.snap @@ -1,6 +1,9 @@ { "ExtraMembers": [], "MissingMembers": [ - "System.IO.Abstractions.FileSystemStream Create(System.String, Int32, System.IO.FileOptions, System.Security.AccessControl.FileSecurity)" + "System.IO.Abstractions.FileSystemStream Create(System.String, Int32, System.IO.FileOptions, System.Security.AccessControl.FileSecurity)", + "System.Security.AccessControl.FileSecurity GetAccessControl(System.String)", + "System.Security.AccessControl.FileSecurity GetAccessControl(System.String, System.Security.AccessControl.AccessControlSections)", + "Void SetAccessControl(System.String, System.Security.AccessControl.FileSecurity)" ] } From 7fd4e89e72715a0ac2e205a55e5f8211eea229fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Tue, 15 Nov 2022 09:14:35 +0100 Subject: [PATCH 09/25] Enable Serialization --- src/System.IO.Abstractions.TestingHelpers/MockFileData.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs b/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs index 350c874be..84048c71c 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs @@ -36,8 +36,11 @@ public class MockFileData /// /// The extensibility of the . /// - public IFileSystemExtensibility Extensibility { get; } - = new FileSystemExtensibility(); + public IFileSystemExtensibility Extensibility + => extensibility; + + [NonSerialized] + private IFileSystemExtensibility extensibility = new FileSystemExtensibility(); /// /// Gets a value indicating whether the is a directory or not. From 67058b5f52037863b479f875486529a0390155b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Tue, 15 Nov 2022 10:36:31 +0100 Subject: [PATCH 10/25] Throw correct exception when file or directory was not found --- .../FileSystemExtensibility.cs | 39 +++++++++++++++++-- .../MockDirectoryData.cs | 6 +-- .../MockDirectoryInfo.cs | 9 ++++- .../MockFileData.cs | 8 ++-- .../MockFileInfo.cs | 14 ++++--- .../DirectoryAclExtensions.cs | 8 ++-- .../DirectoryInfoAclExtensions.cs | 10 ++--- .../FileAclExtensions.cs | 6 +-- .../FileInfoAclExtensions.cs | 6 +-- .../FileStreamAclExtensions.cs | 4 +- 10 files changed, 77 insertions(+), 33 deletions(-) diff --git a/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs b/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs index 4339cd672..b8375f155 100644 --- a/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs +++ b/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs @@ -6,6 +6,8 @@ internal class FileSystemExtensibility : IFileSystemExtensibility { private readonly Dictionary _metadata = new(); + + /// public bool TryGetWrappedInstance(out T wrappedInstance) { @@ -22,13 +24,44 @@ public void StoreMetadata(string key, T value) /// public T RetrieveMetadata(string key) { - if (_metadata.TryGetValue(key, out object value) && - value is T castedValue) + if (_metadata.ContainsKey(key)) { - return castedValue; + var value = _metadata[key]; + if (value is T) + { + return (T) value; + } } return default; } + + public static IFileSystemExtensibility GetNullObject(Func factory) + => new NullFileSystemExtensibility(factory); + + private class NullFileSystemExtensibility : IFileSystemExtensibility + { + private readonly Func _factory; + + public NullFileSystemExtensibility(Func factory) + { + _factory = factory; + } + public bool TryGetWrappedInstance(out T wrappedInstance) + { + wrappedInstance = default; + return false; + } + + public void StoreMetadata(string key, T value) + { + throw _factory.Invoke(); + } + + public T RetrieveMetadata(string key) + { + throw _factory.Invoke(); + } + } } } \ No newline at end of file diff --git a/src/System.IO.Abstractions.TestingHelpers/MockDirectoryData.cs b/src/System.IO.Abstractions.TestingHelpers/MockDirectoryData.cs index d107f3419..ee29705c0 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockDirectoryData.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockDirectoryData.cs @@ -21,16 +21,16 @@ public new DirectorySecurity AccessControl { // DirectorySecurity's constructor will throw PlatformNotSupportedException on non-Windows platform, so we initialize it in lazy way. // This let's us use this class as long as we don't use AccessControl property. - var directorySecurity = Extensibility.RetrieveMetadata("AccessControl"); + var directorySecurity = Extensibility.RetrieveMetadata("AccessControl:Directory"); if (directorySecurity == null) { directorySecurity = new DirectorySecurity(); - Extensibility.StoreMetadata("AccessControl", directorySecurity); + Extensibility.StoreMetadata("AccessControl:Directory", directorySecurity); } return directorySecurity; } - set { Extensibility.StoreMetadata("AccessControl", value); } + set { Extensibility.StoreMetadata("AccessControl:Directory", value); } } } } \ No newline at end of file diff --git a/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs b/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs index 7822bbfe3..915a622ec 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs @@ -100,7 +100,14 @@ public override bool Exists /// public override IFileSystemExtensibility Extensibility - => (mockFileDataAccessor.GetFile(directoryPath) ?? MockFileData.NullObject)?.Extensibility; + { + get + { + var mockFileData = mockFileDataAccessor.GetFile(directoryPath); + return mockFileData?.Extensibility ?? FileSystemExtensibility.GetNullObject( + () =>CommonExceptions.CouldNotFindPartOfPath(directoryPath)); + } + } /// public override string Extension diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs b/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs index 84048c71c..93f9b1196 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs @@ -24,7 +24,7 @@ public class MockFileData LastWriteTime = new DateTime(1601, 01, 01, 00, 00, 00, DateTimeKind.Utc), LastAccessTime = new DateTime(1601, 01, 01, 00, 00, 00, DateTimeKind.Utc), CreationTime = new DateTime(1601, 01, 01, 00, 00, 00, DateTimeKind.Utc), - Attributes = (FileAttributes)(-1), + Attributes = (FileAttributes)(-1) }; /// @@ -193,16 +193,16 @@ public FileSecurity AccessControl { // FileSecurity's constructor will throw PlatformNotSupportedException on non-Windows platform, so we initialize it in lazy way. // This let's us use this class as long as we don't use AccessControl property. - var fileSecurity = Extensibility.RetrieveMetadata("AccessControl"); + var fileSecurity = Extensibility.RetrieveMetadata("AccessControl:File"); if (fileSecurity == null) { fileSecurity = new FileSecurity(); - Extensibility.StoreMetadata("AccessControl", fileSecurity); + Extensibility.StoreMetadata("AccessControl:File", fileSecurity); } return fileSecurity; } - set { Extensibility.StoreMetadata("AccessControl", value); } + set { Extensibility.StoreMetadata("AccessControl:File", value); } } /// diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs b/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs index 66595283a..c8fcdb0f8 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs @@ -1,7 +1,4 @@ -using System.Runtime.Versioning; -using System.Security.AccessControl; - -namespace System.IO.Abstractions.TestingHelpers +namespace System.IO.Abstractions.TestingHelpers { /// [Serializable] @@ -111,7 +108,14 @@ public override bool Exists /// public override IFileSystemExtensibility Extensibility - => (mockFileSystem.GetFile(path) ?? MockFileData.NullObject)?.Extensibility; + { + get + { + var mockFileData = mockFileSystem.GetFile(path); + return mockFileData?.Extensibility ?? FileSystemExtensibility.GetNullObject( + () => CommonExceptions.FileNotFound(path)); + } + } /// public override string Extension diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryAclExtensions.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryAclExtensions.cs index 62082a722..423866bc9 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryAclExtensions.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryAclExtensions.cs @@ -28,7 +28,7 @@ public static class DirectoryAclExtensions } else { - extensibility.StoreMetadata("AccessControl", + extensibility.StoreMetadata("AccessControl:Directory", directorySecurity); directoryInfo.Create(); } @@ -50,7 +50,7 @@ public static class DirectoryAclExtensions return extensibility.TryGetWrappedInstance(out DirectoryInfo di) ? di.GetAccessControl() : extensibility.RetrieveMetadata( - "AccessControl") ?? new DirectorySecurity(); + "AccessControl:Directory") ?? new DirectorySecurity(); } #if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS @@ -71,7 +71,7 @@ public static class DirectoryAclExtensions return extensibility.TryGetWrappedInstance(out DirectoryInfo di) ? di.GetAccessControl(includeSections) : extensibility.RetrieveMetadata( - "AccessControl") ?? new DirectorySecurity(); + "AccessControl:Directory") ?? new DirectorySecurity(); } #if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS @@ -94,7 +94,7 @@ public static class DirectoryAclExtensions } else { - extensibility.StoreMetadata("AccessControl", + extensibility.StoreMetadata("AccessControl:Directory", directorySecurity); } } diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoAclExtensions.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoAclExtensions.cs index e59e6fa0a..b4888282d 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoAclExtensions.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoAclExtensions.cs @@ -25,9 +25,9 @@ public static class DirectoryInfoAclExtensions } else { - extensibility.StoreMetadata("AccessControl", - directorySecurity); directoryInfo.Create(); + directoryInfo.Extensibility.StoreMetadata("AccessControl:Directory", + directorySecurity); } } @@ -45,7 +45,7 @@ public static class DirectoryInfoAclExtensions return extensibility.TryGetWrappedInstance(out DirectoryInfo di) ? di.GetAccessControl() : extensibility.RetrieveMetadata( - "AccessControl") ?? new DirectorySecurity(); + "AccessControl:Directory") ?? new DirectorySecurity(); } #if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS @@ -63,7 +63,7 @@ public static class DirectoryInfoAclExtensions return extensibility.TryGetWrappedInstance(out DirectoryInfo di) ? di.GetAccessControl(includeSections) : extensibility.RetrieveMetadata( - "AccessControl") ?? new DirectorySecurity(); + "AccessControl:Directory") ?? new DirectorySecurity(); } #if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS @@ -83,7 +83,7 @@ public static class DirectoryInfoAclExtensions } else { - extensibility.StoreMetadata("AccessControl", + extensibility.StoreMetadata("AccessControl:Directory", directorySecurity); } } diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/FileAclExtensions.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/FileAclExtensions.cs index be5d1c544..08b64870d 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/FileAclExtensions.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/FileAclExtensions.cs @@ -23,7 +23,7 @@ public static class FileAclExtensions return extensibility.TryGetWrappedInstance(out FileInfo fi) ? fi.GetAccessControl() : extensibility.RetrieveMetadata( - "AccessControl") ?? new FileSecurity(); + "AccessControl:File") ?? new FileSecurity(); } #if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS @@ -43,7 +43,7 @@ public static class FileAclExtensions return extensibility.TryGetWrappedInstance(out FileInfo fi) ? fi.GetAccessControl(includeSections) : extensibility.RetrieveMetadata( - "AccessControl") ?? new FileSecurity(); + "AccessControl:File") ?? new FileSecurity(); } #if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS @@ -65,7 +65,7 @@ public static class FileAclExtensions } else { - extensibility.StoreMetadata("AccessControl", + extensibility.StoreMetadata("AccessControl:File", fileSecurity); } } diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoAclExtensions.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoAclExtensions.cs index ddf310da1..92a0c1ffd 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoAclExtensions.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoAclExtensions.cs @@ -22,7 +22,7 @@ public static class FileInfoAclExtensions return extensibility.TryGetWrappedInstance(out FileInfo fi) ? fi.GetAccessControl() : extensibility.RetrieveMetadata( - "AccessControl") ?? new FileSecurity(); + "AccessControl:File") ?? new FileSecurity(); } #if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS @@ -40,7 +40,7 @@ public static class FileInfoAclExtensions return extensibility.TryGetWrappedInstance(out FileInfo fi) ? fi.GetAccessControl(includeSections) : extensibility.RetrieveMetadata( - "AccessControl") ?? new FileSecurity(); + "AccessControl:File") ?? new FileSecurity(); } #if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS @@ -60,7 +60,7 @@ public static class FileInfoAclExtensions } else { - extensibility.StoreMetadata("AccessControl", + extensibility.StoreMetadata("AccessControl:File", fileSecurity); } } diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/FileStreamAclExtensions.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/FileStreamAclExtensions.cs index be4551344..9c60a6175 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/FileStreamAclExtensions.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/FileStreamAclExtensions.cs @@ -21,7 +21,7 @@ public static FileSecurity GetAccessControl(this FileSystemStream fileStream) return extensibility.TryGetWrappedInstance(out FileStream fs) ? fs.GetAccessControl() : extensibility.RetrieveMetadata( - "AccessControl") ?? new FileSecurity(); + "AccessControl:File") ?? new FileSecurity(); } #if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS @@ -41,7 +41,7 @@ public static FileSecurity GetAccessControl(this FileSystemStream fileStream) } else { - extensibility.StoreMetadata("AccessControl", + extensibility.StoreMetadata("AccessControl:File", fileSecurity); } } From ccc766aaee83eb986885ae921bd5d0839c2c8902 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Tue, 15 Nov 2022 10:59:20 +0100 Subject: [PATCH 11/25] Adjust tests --- .../MockDirectoryInfo.cs | 12 +++++++++++- .../MockFileInfo.cs | 1 + .../MockFileAdjustTimesTest.cs | 4 ++-- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs b/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs index 915a622ec..c201f624b 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs @@ -25,8 +25,17 @@ public class MockDirectoryInfo : DirectoryInfoBase public MockDirectoryInfo(IMockFileDataAccessor mockFileDataAccessor, string directoryPath) : base(mockFileDataAccessor?.FileSystem) { this.mockFileDataAccessor = mockFileDataAccessor ?? throw new ArgumentNullException(nameof(mockFileDataAccessor)); - + originalPath = directoryPath; + + if (directoryPath== null) + { + throw new ArgumentNullException("path", StringResources.Manager.GetString("VALUE_CANNOT_BE_NULL")); + } + if (directoryPath.Trim() == string.Empty) + { + throw CommonExceptions.PathIsNotOfALegalForm("path"); + } directoryPath = mockFileDataAccessor.Path.GetFullPath(directoryPath); directoryPath = directoryPath.TrimSlashes(); @@ -35,6 +44,7 @@ public MockDirectoryInfo(IMockFileDataAccessor mockFileDataAccessor, string dire directoryPath = directoryPath.TrimEnd(' '); } this.directoryPath = directoryPath; + Refresh(); } diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs b/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs index c8fcdb0f8..77c212093 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs @@ -16,6 +16,7 @@ public MockFileInfo(IMockFileDataAccessor mockFileSystem, string path) : base(mo { this.mockFileSystem = mockFileSystem ?? throw new ArgumentNullException(nameof(mockFileSystem)); this.originalPath = path ?? throw new ArgumentNullException(nameof(path)); + mockFileSystem.PathVerifier.IsLegalAbsoluteOrRelative(path, "path"); this.path = mockFileSystem.Path.GetFullPath(path); this.mockFile = new MockFile(mockFileSystem); Refresh(); diff --git a/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileAdjustTimesTest.cs b/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileAdjustTimesTest.cs index e9feb27ab..5413c3911 100644 --- a/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileAdjustTimesTest.cs +++ b/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileAdjustTimesTest.cs @@ -201,7 +201,7 @@ public void MockFile_AfterSetAttributes_ShouldUpdateLastAccessTime() [Test] [SupportedOSPlatform("windows")] [WindowsOnly(WindowsSpecifics.AccessControlLists)] - public void MockFile_AfterSetAccessControl_ShouldUpdateLastAccessTime() + public void MockFile_AfterSetAccessControl_ShouldNotUpdateLastAccessTime() { var creationTime = DateTime.UtcNow.AddDays(10); var updateTime = creationTime.AddDays(10); @@ -216,7 +216,7 @@ public void MockFile_AfterSetAccessControl_ShouldUpdateLastAccessTime() var actualLastWriteTime = fileSystem.File.GetLastWriteTimeUtc("foo.txt"); Assert.That(actualCreationTime, Is.EqualTo(creationTime)); - Assert.That(actualLastAccessTime, Is.EqualTo(updateTime)); + Assert.That(actualLastAccessTime, Is.EqualTo(creationTime)); Assert.That(actualLastWriteTime, Is.EqualTo(creationTime)); } From af1ecbd5b0cdd83589c77959d5a3abe81422d72e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Tue, 15 Nov 2022 11:02:15 +0100 Subject: [PATCH 12/25] Revert not-working changes to global.json --- global.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/global.json b/global.json index 77c776f82..cd688df74 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "7.0.100", + "version": "6.0.403", "rollForward": "latestFeature" } -} +} \ No newline at end of file From 94a82c22e5dd26a5e40136899c08328c0cd1e1fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Tue, 15 Nov 2022 11:10:20 +0100 Subject: [PATCH 13/25] Cleanup --- global.json | 2 +- .../FileSystemExtensibility.cs | 25 ++++++++----------- .../MockDirectoryData.cs | 6 ++--- .../MockDirectoryInfo.cs | 5 ++-- .../MockFileData.cs | 8 +++--- .../DirectoryAclExtensions.cs | 10 ++++---- .../DirectoryInfoAclExtensions.cs | 10 ++++---- .../FileAclExtensions.cs | 8 +++--- .../FileInfoAclExtensions.cs | 8 +++--- .../FileStreamAclExtensions.cs | 6 ++--- .../IFileSystemExtensibility.cs | 2 +- .../MockFileAdjustTimesTest.cs | 2 +- 12 files changed, 43 insertions(+), 49 deletions(-) diff --git a/global.json b/global.json index cd688df74..cb8c6c79d 100644 --- a/global.json +++ b/global.json @@ -3,4 +3,4 @@ "version": "6.0.403", "rollForward": "latestFeature" } -} \ No newline at end of file +} diff --git a/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs b/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs index b8375f155..8831cbd9f 100644 --- a/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs +++ b/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs @@ -6,8 +6,6 @@ internal class FileSystemExtensibility : IFileSystemExtensibility { private readonly Dictionary _metadata = new(); - - /// public bool TryGetWrappedInstance(out T wrappedInstance) { @@ -24,28 +22,25 @@ public void StoreMetadata(string key, T value) /// public T RetrieveMetadata(string key) { - if (_metadata.ContainsKey(key)) + if (_metadata.TryGetValue(key, out object value) && + value is T castedValue) { - var value = _metadata[key]; - if (value is T) - { - return (T) value; - } + return castedValue; } return default; } - public static IFileSystemExtensibility GetNullObject(Func factory) - => new NullFileSystemExtensibility(factory); + public static IFileSystemExtensibility GetNullObject(Func exceptionFactory) + => new NullFileSystemExtensibility(exceptionFactory); private class NullFileSystemExtensibility : IFileSystemExtensibility { - private readonly Func _factory; + private readonly Func _exceptionFactory; - public NullFileSystemExtensibility(Func factory) + public NullFileSystemExtensibility(Func exceptionFactory) { - _factory = factory; + _exceptionFactory = exceptionFactory; } public bool TryGetWrappedInstance(out T wrappedInstance) { @@ -55,12 +50,12 @@ public bool TryGetWrappedInstance(out T wrappedInstance) public void StoreMetadata(string key, T value) { - throw _factory.Invoke(); + throw _exceptionFactory.Invoke(); } public T RetrieveMetadata(string key) { - throw _factory.Invoke(); + throw _exceptionFactory.Invoke(); } } } diff --git a/src/System.IO.Abstractions.TestingHelpers/MockDirectoryData.cs b/src/System.IO.Abstractions.TestingHelpers/MockDirectoryData.cs index ee29705c0..6616e3f4d 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockDirectoryData.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockDirectoryData.cs @@ -21,16 +21,16 @@ public new DirectorySecurity AccessControl { // DirectorySecurity's constructor will throw PlatformNotSupportedException on non-Windows platform, so we initialize it in lazy way. // This let's us use this class as long as we don't use AccessControl property. - var directorySecurity = Extensibility.RetrieveMetadata("AccessControl:Directory"); + var directorySecurity = Extensibility.RetrieveMetadata("AccessControl:DirectorySecurity"); if (directorySecurity == null) { directorySecurity = new DirectorySecurity(); - Extensibility.StoreMetadata("AccessControl:Directory", directorySecurity); + Extensibility.StoreMetadata("AccessControl:DirectorySecurity", directorySecurity); } return directorySecurity; } - set { Extensibility.StoreMetadata("AccessControl:Directory", value); } + set { Extensibility.StoreMetadata("AccessControl:DirectorySecurity", value); } } } } \ No newline at end of file diff --git a/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs b/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs index c201f624b..9fe4c30f3 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs @@ -25,7 +25,7 @@ public class MockDirectoryInfo : DirectoryInfoBase public MockDirectoryInfo(IMockFileDataAccessor mockFileDataAccessor, string directoryPath) : base(mockFileDataAccessor?.FileSystem) { this.mockFileDataAccessor = mockFileDataAccessor ?? throw new ArgumentNullException(nameof(mockFileDataAccessor)); - + originalPath = directoryPath; if (directoryPath== null) @@ -44,7 +44,6 @@ public MockDirectoryInfo(IMockFileDataAccessor mockFileDataAccessor, string dire directoryPath = directoryPath.TrimEnd(' '); } this.directoryPath = directoryPath; - Refresh(); } @@ -115,7 +114,7 @@ public override IFileSystemExtensibility Extensibility { var mockFileData = mockFileDataAccessor.GetFile(directoryPath); return mockFileData?.Extensibility ?? FileSystemExtensibility.GetNullObject( - () =>CommonExceptions.CouldNotFindPartOfPath(directoryPath)); + () => CommonExceptions.CouldNotFindPartOfPath(directoryPath)); } } diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs b/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs index 93f9b1196..dcf339847 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs @@ -24,7 +24,7 @@ public class MockFileData LastWriteTime = new DateTime(1601, 01, 01, 00, 00, 00, DateTimeKind.Utc), LastAccessTime = new DateTime(1601, 01, 01, 00, 00, 00, DateTimeKind.Utc), CreationTime = new DateTime(1601, 01, 01, 00, 00, 00, DateTimeKind.Utc), - Attributes = (FileAttributes)(-1) + Attributes = (FileAttributes)(-1), }; /// @@ -193,16 +193,16 @@ public FileSecurity AccessControl { // FileSecurity's constructor will throw PlatformNotSupportedException on non-Windows platform, so we initialize it in lazy way. // This let's us use this class as long as we don't use AccessControl property. - var fileSecurity = Extensibility.RetrieveMetadata("AccessControl:File"); + var fileSecurity = Extensibility.RetrieveMetadata("AccessControl:FileSecurity"); if (fileSecurity == null) { fileSecurity = new FileSecurity(); - Extensibility.StoreMetadata("AccessControl:File", fileSecurity); + Extensibility.StoreMetadata("AccessControl:FileSecurity", fileSecurity); } return fileSecurity; } - set { Extensibility.StoreMetadata("AccessControl:File", value); } + set { Extensibility.StoreMetadata("AccessControl:FileSecurity", value); } } /// diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryAclExtensions.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryAclExtensions.cs index 423866bc9..1be4f5b3a 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryAclExtensions.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryAclExtensions.cs @@ -28,7 +28,7 @@ public static class DirectoryAclExtensions } else { - extensibility.StoreMetadata("AccessControl:Directory", + extensibility.StoreMetadata("AccessControl:DirectorySecurity", directorySecurity); directoryInfo.Create(); } @@ -50,7 +50,7 @@ public static class DirectoryAclExtensions return extensibility.TryGetWrappedInstance(out DirectoryInfo di) ? di.GetAccessControl() : extensibility.RetrieveMetadata( - "AccessControl:Directory") ?? new DirectorySecurity(); + "AccessControl:DirectorySecurity") ?? new DirectorySecurity(); } #if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS @@ -71,7 +71,7 @@ public static class DirectoryAclExtensions return extensibility.TryGetWrappedInstance(out DirectoryInfo di) ? di.GetAccessControl(includeSections) : extensibility.RetrieveMetadata( - "AccessControl:Directory") ?? new DirectorySecurity(); + "AccessControl:DirectorySecurity") ?? new DirectorySecurity(); } #if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS @@ -94,9 +94,9 @@ public static class DirectoryAclExtensions } else { - extensibility.StoreMetadata("AccessControl:Directory", + extensibility.StoreMetadata("AccessControl:DirectorySecurity", directorySecurity); } } } -} \ No newline at end of file +} diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoAclExtensions.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoAclExtensions.cs index b4888282d..87f421b78 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoAclExtensions.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoAclExtensions.cs @@ -26,7 +26,7 @@ public static class DirectoryInfoAclExtensions else { directoryInfo.Create(); - directoryInfo.Extensibility.StoreMetadata("AccessControl:Directory", + directoryInfo.Extensibility.StoreMetadata("AccessControl:DirectorySecurity", directorySecurity); } } @@ -45,7 +45,7 @@ public static class DirectoryInfoAclExtensions return extensibility.TryGetWrappedInstance(out DirectoryInfo di) ? di.GetAccessControl() : extensibility.RetrieveMetadata( - "AccessControl:Directory") ?? new DirectorySecurity(); + "AccessControl:DirectorySecurity") ?? new DirectorySecurity(); } #if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS @@ -63,7 +63,7 @@ public static class DirectoryInfoAclExtensions return extensibility.TryGetWrappedInstance(out DirectoryInfo di) ? di.GetAccessControl(includeSections) : extensibility.RetrieveMetadata( - "AccessControl:Directory") ?? new DirectorySecurity(); + "AccessControl:DirectorySecurity") ?? new DirectorySecurity(); } #if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS @@ -83,9 +83,9 @@ public static class DirectoryInfoAclExtensions } else { - extensibility.StoreMetadata("AccessControl:Directory", + extensibility.StoreMetadata("AccessControl:DirectorySecurity", directorySecurity); } } } -} \ No newline at end of file +} diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/FileAclExtensions.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/FileAclExtensions.cs index 08b64870d..8fb1657f1 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/FileAclExtensions.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/FileAclExtensions.cs @@ -23,7 +23,7 @@ public static class FileAclExtensions return extensibility.TryGetWrappedInstance(out FileInfo fi) ? fi.GetAccessControl() : extensibility.RetrieveMetadata( - "AccessControl:File") ?? new FileSecurity(); + "AccessControl:FileSecurity") ?? new FileSecurity(); } #if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS @@ -43,7 +43,7 @@ public static class FileAclExtensions return extensibility.TryGetWrappedInstance(out FileInfo fi) ? fi.GetAccessControl(includeSections) : extensibility.RetrieveMetadata( - "AccessControl:File") ?? new FileSecurity(); + "AccessControl:FileSecurity") ?? new FileSecurity(); } #if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS @@ -65,9 +65,9 @@ public static class FileAclExtensions } else { - extensibility.StoreMetadata("AccessControl:File", + extensibility.StoreMetadata("AccessControl:FileSecurity", fileSecurity); } } } -} \ No newline at end of file +} diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoAclExtensions.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoAclExtensions.cs index 92a0c1ffd..e807b66e9 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoAclExtensions.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoAclExtensions.cs @@ -22,7 +22,7 @@ public static class FileInfoAclExtensions return extensibility.TryGetWrappedInstance(out FileInfo fi) ? fi.GetAccessControl() : extensibility.RetrieveMetadata( - "AccessControl:File") ?? new FileSecurity(); + "AccessControl:FileSecurity") ?? new FileSecurity(); } #if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS @@ -40,7 +40,7 @@ public static class FileInfoAclExtensions return extensibility.TryGetWrappedInstance(out FileInfo fi) ? fi.GetAccessControl(includeSections) : extensibility.RetrieveMetadata( - "AccessControl:File") ?? new FileSecurity(); + "AccessControl:FileSecurity") ?? new FileSecurity(); } #if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS @@ -60,9 +60,9 @@ public static class FileInfoAclExtensions } else { - extensibility.StoreMetadata("AccessControl:File", + extensibility.StoreMetadata("AccessControl:FileSecurity", fileSecurity); } } } -} \ No newline at end of file +} diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/FileStreamAclExtensions.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/FileStreamAclExtensions.cs index 9c60a6175..068860fc4 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/FileStreamAclExtensions.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/FileStreamAclExtensions.cs @@ -21,7 +21,7 @@ public static FileSecurity GetAccessControl(this FileSystemStream fileStream) return extensibility.TryGetWrappedInstance(out FileStream fs) ? fs.GetAccessControl() : extensibility.RetrieveMetadata( - "AccessControl:File") ?? new FileSecurity(); + "AccessControl:FileSecurity") ?? new FileSecurity(); } #if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS @@ -41,9 +41,9 @@ public static FileSecurity GetAccessControl(this FileSystemStream fileStream) } else { - extensibility.StoreMetadata("AccessControl:File", + extensibility.StoreMetadata("AccessControl:FileSecurity", fileSecurity); } } } -} \ No newline at end of file +} diff --git a/src/TestableIO.System.IO.Abstractions/IFileSystemExtensibility.cs b/src/TestableIO.System.IO.Abstractions/IFileSystemExtensibility.cs index 72d59ee73..f8d6b86c3 100644 --- a/src/TestableIO.System.IO.Abstractions/IFileSystemExtensibility.cs +++ b/src/TestableIO.System.IO.Abstractions/IFileSystemExtensibility.cs @@ -34,4 +34,4 @@ public interface IFileSystemExtensibility /// The value of the previously stored metadata, or . T? RetrieveMetadata(string key); } -} \ No newline at end of file +} diff --git a/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileAdjustTimesTest.cs b/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileAdjustTimesTest.cs index 5413c3911..caff0b4c1 100644 --- a/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileAdjustTimesTest.cs +++ b/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileAdjustTimesTest.cs @@ -201,7 +201,7 @@ public void MockFile_AfterSetAttributes_ShouldUpdateLastAccessTime() [Test] [SupportedOSPlatform("windows")] [WindowsOnly(WindowsSpecifics.AccessControlLists)] - public void MockFile_AfterSetAccessControl_ShouldNotUpdateLastAccessTime() + public void MockFile_AfterSetAccessControl_ShouldUpdateLastAccessTime() { var creationTime = DateTime.UtcNow.AddDays(10); var updateTime = creationTime.AddDays(10); From 43042efcc9496a86053fae25c72debb3fee8c2d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Tue, 15 Nov 2022 14:51:11 +0100 Subject: [PATCH 14/25] Fix lazy initialization of AccessControl --- .../FileSystemExtensibility.cs | 8 ++++++++ src/System.IO.Abstractions.TestingHelpers/MockFileData.cs | 8 +++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs b/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs index 8831cbd9f..d78528c35 100644 --- a/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs +++ b/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs @@ -31,6 +31,14 @@ public T RetrieveMetadata(string key) return default; } + internal void Clone(FileSystemExtensibility template) + { + foreach (var item in template._metadata) + { + _metadata[item.Key] = item.Value; + } + } + public static IFileSystemExtensibility GetNullObject(Func exceptionFactory) => new NullFileSystemExtensibility(exceptionFactory); diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs b/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs index dcf339847..550a6a255 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs @@ -40,7 +40,7 @@ public IFileSystemExtensibility Extensibility => extensibility; [NonSerialized] - private IFileSystemExtensibility extensibility = new FileSystemExtensibility(); + private FileSystemExtensibility extensibility = new FileSystemExtensibility(); /// /// Gets a value indicating whether the is a directory or not. @@ -101,10 +101,8 @@ public MockFileData(MockFileData template) { throw new ArgumentNullException(nameof(template)); } - -#pragma warning disable CA1416 - AccessControl = template.AccessControl; -#pragma warning restore CA1416 + + extensibility.Clone(template.extensibility); Attributes = template.Attributes; Contents = template.Contents.ToArray(); CreationTime = template.CreationTime; From f02b929a5dc5ceaea4dd08d4209c3a71ea93a5e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Wed, 16 Nov 2022 20:17:44 +0100 Subject: [PATCH 15/25] Update src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs Co-authored-by: Peter Baumann --- src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs b/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs index 77c212093..46fb8ceac 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs @@ -15,8 +15,8 @@ public class MockFileInfo : FileInfoBase public MockFileInfo(IMockFileDataAccessor mockFileSystem, string path) : base(mockFileSystem?.FileSystem) { this.mockFileSystem = mockFileSystem ?? throw new ArgumentNullException(nameof(mockFileSystem)); - this.originalPath = path ?? throw new ArgumentNullException(nameof(path)); mockFileSystem.PathVerifier.IsLegalAbsoluteOrRelative(path, "path"); + this.originalPath = path; this.path = mockFileSystem.Path.GetFullPath(path); this.mockFile = new MockFile(mockFileSystem); Refresh(); From e96ea488b1a073266e9d687cf7e384ac86958bac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Wed, 16 Nov 2022 20:20:38 +0100 Subject: [PATCH 16/25] Update src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs Co-authored-by: Peter Baumann --- .../MockDirectoryInfo.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs b/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs index 9fe4c30f3..e285f11ce 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs @@ -26,8 +26,6 @@ public MockDirectoryInfo(IMockFileDataAccessor mockFileDataAccessor, string dire { this.mockFileDataAccessor = mockFileDataAccessor ?? throw new ArgumentNullException(nameof(mockFileDataAccessor)); - originalPath = directoryPath; - if (directoryPath== null) { throw new ArgumentNullException("path", StringResources.Manager.GetString("VALUE_CANNOT_BE_NULL")); @@ -36,6 +34,8 @@ public MockDirectoryInfo(IMockFileDataAccessor mockFileDataAccessor, string dire { throw CommonExceptions.PathIsNotOfALegalForm("path"); } + + originalPath = directoryPath; directoryPath = mockFileDataAccessor.Path.GetFullPath(directoryPath); directoryPath = directoryPath.TrimSlashes(); From bd5f6bfb099971a13f51eb22d31db9a97c3f7365 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Sun, 20 Nov 2022 07:51:14 +0100 Subject: [PATCH 17/25] Fix Codacy-Issues --- .../FileSystemExtensibility.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs b/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs index d78528c35..8e8bc2121 100644 --- a/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs +++ b/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs @@ -13,13 +13,13 @@ public bool TryGetWrappedInstance(out T wrappedInstance) return false; } - /// + /// public void StoreMetadata(string key, T value) { _metadata[key] = value; } - /// + /// public T RetrieveMetadata(string key) { if (_metadata.TryGetValue(key, out object value) && @@ -50,19 +50,26 @@ public NullFileSystemExtensibility(Func exceptionFactory) { _exceptionFactory = exceptionFactory; } + + /// public bool TryGetWrappedInstance(out T wrappedInstance) { wrappedInstance = default; return false; } + /// public void StoreMetadata(string key, T value) { + _ = key; + _ = value; throw _exceptionFactory.Invoke(); } + /// public T RetrieveMetadata(string key) { + _ = key; throw _exceptionFactory.Invoke(); } } From 76e320b4e5882161e311cec88c8af172e118fcf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Mon, 21 Nov 2022 14:31:29 +0100 Subject: [PATCH 18/25] Rename "Clone" to "CloneFrom" --- .../FileSystemExtensibility.cs | 2 +- src/System.IO.Abstractions.TestingHelpers/MockFileData.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs b/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs index 8e8bc2121..2f1eb31bb 100644 --- a/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs +++ b/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs @@ -31,7 +31,7 @@ public T RetrieveMetadata(string key) return default; } - internal void Clone(FileSystemExtensibility template) + internal void CloneFrom(FileSystemExtensibility template) { foreach (var item in template._metadata) { diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs b/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs index 550a6a255..572f7bdfa 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs @@ -102,7 +102,7 @@ public MockFileData(MockFileData template) throw new ArgumentNullException(nameof(template)); } - extensibility.Clone(template.extensibility); + extensibility.CloneFrom(template.extensibility); Attributes = template.Attributes; Contents = template.Contents.ToArray(); CreationTime = template.CreationTime; From fe9efba0679e4e305bf818607df8991687a042bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Wed, 23 Nov 2022 08:44:20 +0100 Subject: [PATCH 19/25] Implement review findings: - Replace IFileSystemExtensibility with IFileSystemAclSupport --- .../FileSystemExtensibility.cs | 45 ++++--------- .../MockDirectoryData.cs | 4 +- .../MockDirectoryInfo.cs | 34 ++++++---- .../MockFileData.cs | 6 +- .../MockFileInfo.cs | 38 +++++++---- .../MockFileStream.cs | 28 +++++++-- .../DirectoryAclExtensions.cs | 51 +++------------ .../DirectoryInfoAclExtensions.cs | 58 ++++++++--------- .../DirectoryInfoWrapper.cs | 28 +++++++-- .../FileAclExtensions.cs | 26 +------- .../FileInfoAclExtensions.cs | 42 ++++++------- .../FileInfoWrapper.cs | 27 ++++++-- .../FileStreamAclExtensions.cs | 31 +++++---- .../FileStreamWrapper.cs | 33 ++++++++-- .../FileSystemExtensibility.cs | 46 -------------- .../FileSystemInfoBase.cs | 3 - .../FileSystemStream.cs | 5 -- .../IFileSystemAclSupport.cs | 63 +++++++++++++++++++ .../IFileSystemExtensibility.cs | 37 ----------- .../IFileSystemInfo.cs | 5 -- ...ApiParityTests.DirectoryInfo_.NET 5.0.snap | 5 +- ...ApiParityTests.DirectoryInfo_.NET 6.0.snap | 5 +- ...rityTests.DirectoryInfo_.NET Core 3.1.snap | 5 +- ...ts.DirectoryInfo_.NET Framework 4.6.1.snap | 5 +- .../ApiParityTests.FileInfo_.NET 5.0.snap | 5 +- .../ApiParityTests.FileInfo_.NET 6.0.snap | 5 +- ...ApiParityTests.FileInfo_.NET Core 3.1.snap | 5 +- ...tyTests.FileInfo_.NET Framework 4.6.1.snap | 5 +- 28 files changed, 306 insertions(+), 344 deletions(-) delete mode 100644 src/TestableIO.System.IO.Abstractions.Wrappers/FileSystemExtensibility.cs create mode 100644 src/TestableIO.System.IO.Abstractions/IFileSystemAclSupport.cs delete mode 100644 src/TestableIO.System.IO.Abstractions/IFileSystemExtensibility.cs diff --git a/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs b/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs index 2f1eb31bb..099dbb990 100644 --- a/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs +++ b/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs @@ -2,30 +2,20 @@ namespace System.IO.Abstractions.TestingHelpers { - internal class FileSystemExtensibility : IFileSystemExtensibility + internal class FileSystemExtensibility { private readonly Dictionary _metadata = new(); - - /// - public bool TryGetWrappedInstance(out T wrappedInstance) - { - wrappedInstance = default; - return false; - } - - /// - public void StoreMetadata(string key, T value) + + public virtual void StoreMetadata(string key, object value) { _metadata[key] = value; } - - /// - public T RetrieveMetadata(string key) + + public virtual object RetrieveMetadata(string key) { - if (_metadata.TryGetValue(key, out object value) && - value is T castedValue) + if (_metadata.TryGetValue(key, out object value)) { - return castedValue; + return value; } return default; @@ -39,10 +29,10 @@ internal void CloneFrom(FileSystemExtensibility template) } } - public static IFileSystemExtensibility GetNullObject(Func exceptionFactory) + public static FileSystemExtensibility GetNullObject(Func exceptionFactory) => new NullFileSystemExtensibility(exceptionFactory); - private class NullFileSystemExtensibility : IFileSystemExtensibility + private sealed class NullFileSystemExtensibility : FileSystemExtensibility { private readonly Func _exceptionFactory; @@ -50,24 +40,15 @@ public NullFileSystemExtensibility(Func exceptionFactory) { _exceptionFactory = exceptionFactory; } - - /// - public bool TryGetWrappedInstance(out T wrappedInstance) - { - wrappedInstance = default; - return false; - } - - /// - public void StoreMetadata(string key, T value) + + public override void StoreMetadata(string key, object value) { _ = key; _ = value; throw _exceptionFactory.Invoke(); } - - /// - public T RetrieveMetadata(string key) + + public override object RetrieveMetadata(string key) { _ = key; throw _exceptionFactory.Invoke(); diff --git a/src/System.IO.Abstractions.TestingHelpers/MockDirectoryData.cs b/src/System.IO.Abstractions.TestingHelpers/MockDirectoryData.cs index 6616e3f4d..41103f2d7 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockDirectoryData.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockDirectoryData.cs @@ -21,8 +21,8 @@ public new DirectorySecurity AccessControl { // DirectorySecurity's constructor will throw PlatformNotSupportedException on non-Windows platform, so we initialize it in lazy way. // This let's us use this class as long as we don't use AccessControl property. - var directorySecurity = Extensibility.RetrieveMetadata("AccessControl:DirectorySecurity"); - if (directorySecurity == null) + var value = Extensibility.RetrieveMetadata("AccessControl:DirectorySecurity"); + if (value is not DirectorySecurity directorySecurity) { directorySecurity = new DirectorySecurity(); Extensibility.StoreMetadata("AccessControl:DirectorySecurity", directorySecurity); diff --git a/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs b/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs index e285f11ce..4b444a8b9 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using System.Runtime.Versioning; using System.Security.AccessControl; namespace System.IO.Abstractions.TestingHelpers @@ -8,7 +9,7 @@ namespace System.IO.Abstractions.TestingHelpers /// [Serializable] - public class MockDirectoryInfo : DirectoryInfoBase + public class MockDirectoryInfo : DirectoryInfoBase, IFileSystemAclSupport { private readonly IMockFileDataAccessor mockFileDataAccessor; private readonly string directoryPath; @@ -107,17 +108,6 @@ public override bool Exists } } - /// - public override IFileSystemExtensibility Extensibility - { - get - { - var mockFileData = mockFileDataAccessor.GetFile(directoryPath); - return mockFileData?.Extensibility ?? FileSystemExtensibility.GetNullObject( - () => CommonExceptions.CouldNotFindPartOfPath(directoryPath)); - } - } - /// public override string Extension { @@ -430,5 +420,25 @@ public override string ToString() { return originalPath; } + + /// + [SupportedOSPlatform("windows")] + public object GetAccessControl(IFileSystemAclSupport.AccessControlSections includeSections = IFileSystemAclSupport.AccessControlSections.Default) + { + return GetMockDirectoryData().AccessControl; + } + + /// + [SupportedOSPlatform("windows")] + public void SetAccessControl(object value) + { + GetMockDirectoryData().AccessControl = value as DirectorySecurity; + } + + private MockDirectoryData GetMockDirectoryData() + { + return mockFileDataAccessor.GetFile(directoryPath) as MockDirectoryData + ?? throw CommonExceptions.CouldNotFindPartOfPath(directoryPath); + } } } diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs b/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs index 572f7bdfa..42792b6f7 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs @@ -36,7 +36,7 @@ public class MockFileData /// /// The extensibility of the . /// - public IFileSystemExtensibility Extensibility + internal FileSystemExtensibility Extensibility => extensibility; [NonSerialized] @@ -191,8 +191,8 @@ public FileSecurity AccessControl { // FileSecurity's constructor will throw PlatformNotSupportedException on non-Windows platform, so we initialize it in lazy way. // This let's us use this class as long as we don't use AccessControl property. - var fileSecurity = Extensibility.RetrieveMetadata("AccessControl:FileSecurity"); - if (fileSecurity == null) + var value = Extensibility.RetrieveMetadata("AccessControl:FileSecurity"); + if (value is not FileSecurity fileSecurity) { fileSecurity = new FileSecurity(); Extensibility.StoreMetadata("AccessControl:FileSecurity", fileSecurity); diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs b/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs index 46fb8ceac..83ffee41d 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs @@ -1,8 +1,11 @@ -namespace System.IO.Abstractions.TestingHelpers +using System.Runtime.Versioning; +using System.Security.AccessControl; + +namespace System.IO.Abstractions.TestingHelpers { /// [Serializable] - public class MockFileInfo : FileInfoBase + public class MockFileInfo : FileInfoBase, IFileSystemAclSupport { private readonly IMockFileDataAccessor mockFileSystem; private string path; @@ -107,17 +110,6 @@ public override bool Exists } } - /// - public override IFileSystemExtensibility Extensibility - { - get - { - var mockFileData = mockFileSystem.GetFile(path); - return mockFileData?.Extensibility ?? FileSystemExtensibility.GetNullObject( - () => CommonExceptions.FileNotFound(path)); - } - } - /// public override string Extension { @@ -392,6 +384,26 @@ public override string ToString() return originalPath; } + /// + [SupportedOSPlatform("windows")] + public object GetAccessControl(IFileSystemAclSupport.AccessControlSections includeSections = IFileSystemAclSupport.AccessControlSections.Default) + { + return GetMockFileData().AccessControl; + } + + /// + [SupportedOSPlatform("windows")] + public void SetAccessControl(object value) + { + GetMockFileData().AccessControl = value as FileSecurity; + } + + private MockFileData GetMockFileData() + { + return mockFileSystem.GetFile(path) + ?? throw CommonExceptions.FileNotFound(path); + } + private static DateTime AdjustUnspecifiedKind(DateTime time, DateTimeKind fallbackKind) { if (time.Kind == DateTimeKind.Unspecified) diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFileStream.cs b/src/System.IO.Abstractions.TestingHelpers/MockFileStream.cs index 51a1f8656..dff4a17bb 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFileStream.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFileStream.cs @@ -1,11 +1,12 @@ using System.Threading.Tasks; using System.Threading; +using System.Runtime.Versioning; namespace System.IO.Abstractions.TestingHelpers { /// [Serializable] - public class MockFileStream : FileSystemStream + public class MockFileStream : FileSystemStream, IFileSystemAclSupport { private readonly IMockFileDataAccessor mockFileDataAccessor; private readonly string path; @@ -26,7 +27,6 @@ public class MockFileStream : FileSystemStream (options & FileOptions.Asynchronous) != 0) { - this.Extensibility = new FileSystemExtensibility(); this.mockFileDataAccessor = mockFileDataAccessor ?? throw new ArgumentNullException(nameof(mockFileDataAccessor)); this.path = path; this.options = options; @@ -114,9 +114,6 @@ public override void EndWrite(IAsyncResult asyncResult) base.EndWrite(asyncResult); } - /// - public override IFileSystemExtensibility Extensibility { get; } - /// public override void SetLength(long value) { @@ -200,6 +197,27 @@ public override void Flush() InternalFlush(); } + /// + [SupportedOSPlatform("windows")] + public object GetAccessControl(IFileSystemAclSupport.AccessControlSections includeSections = IFileSystemAclSupport.AccessControlSections.Default) + { + return GetExtensibility().RetrieveMetadata("AccessControl:FileSecurity"); + } + + /// + [SupportedOSPlatform("windows")] + public void SetAccessControl(object value) + { + GetExtensibility().StoreMetadata("AccessControl:FileSecurity", value); + } + + private FileSystemExtensibility GetExtensibility() + { + var mockFileData = mockFileDataAccessor.GetFile(path); + return mockFileData?.Extensibility ?? FileSystemExtensibility.GetNullObject( + () => CommonExceptions.FileNotFound(path)); + } + private void InternalFlush() { if (mockFileDataAccessor.FileExists(path)) diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryAclExtensions.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryAclExtensions.cs index 1be4f5b3a..b1052dd8d 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryAclExtensions.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryAclExtensions.cs @@ -18,20 +18,8 @@ public static class DirectoryAclExtensions string path, DirectorySecurity directorySecurity) { - IDirectoryInfo directoryInfo = - directory.FileSystem.DirectoryInfo.New(path); - IFileSystemExtensibility extensibility = - directoryInfo.Extensibility; - if (extensibility.TryGetWrappedInstance(out DirectoryInfo di)) - { - di.Create(directorySecurity); - } - else - { - extensibility.StoreMetadata("AccessControl:DirectorySecurity", - directorySecurity); - directoryInfo.Create(); - } + IDirectoryInfo directoryInfo = directory.FileSystem.DirectoryInfo.New(path); + directoryInfo.Create(directorySecurity); } #if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS @@ -43,14 +31,8 @@ public static class DirectoryAclExtensions public static DirectorySecurity GetAccessControl( this IDirectory directory, string path) { - IDirectoryInfo directoryInfo = - directory.FileSystem.DirectoryInfo.New(path); - IFileSystemExtensibility extensibility = - directoryInfo.Extensibility; - return extensibility.TryGetWrappedInstance(out DirectoryInfo di) - ? di.GetAccessControl() - : extensibility.RetrieveMetadata( - "AccessControl:DirectorySecurity") ?? new DirectorySecurity(); + IDirectoryInfo directoryInfo = directory.FileSystem.DirectoryInfo.New(path); + return directoryInfo.GetAccessControl(); } #if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS @@ -64,14 +46,8 @@ public static class DirectoryAclExtensions string path, AccessControlSections includeSections) { - IDirectoryInfo directoryInfo = - directory.FileSystem.DirectoryInfo.New(path); - IFileSystemExtensibility extensibility = - directoryInfo.Extensibility; - return extensibility.TryGetWrappedInstance(out DirectoryInfo di) - ? di.GetAccessControl(includeSections) - : extensibility.RetrieveMetadata( - "AccessControl:DirectorySecurity") ?? new DirectorySecurity(); + IDirectoryInfo directoryInfo = directory.FileSystem.DirectoryInfo.New(path); + return directoryInfo.GetAccessControl(includeSections); } #if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS @@ -84,19 +60,8 @@ public static class DirectoryAclExtensions string path, DirectorySecurity directorySecurity) { - IDirectoryInfo directoryInfo = - directory.FileSystem.DirectoryInfo.New(path); - IFileSystemExtensibility extensibility = - directoryInfo.Extensibility; - if (extensibility.TryGetWrappedInstance(out DirectoryInfo di)) - { - di.SetAccessControl(directorySecurity); - } - else - { - extensibility.StoreMetadata("AccessControl:DirectorySecurity", - directorySecurity); - } + IDirectoryInfo directoryInfo = directory.FileSystem.DirectoryInfo.New(path); + directoryInfo.SetAccessControl(directorySecurity); } } } diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoAclExtensions.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoAclExtensions.cs index 87f421b78..eacfd4489 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoAclExtensions.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoAclExtensions.cs @@ -17,18 +17,14 @@ public static class DirectoryInfoAclExtensions public static void Create(this IDirectoryInfo directoryInfo, DirectorySecurity directorySecurity) { - IFileSystemExtensibility extensibility = - directoryInfo.Extensibility; - if (extensibility.TryGetWrappedInstance(out DirectoryInfo di)) + IFileSystemAclSupport aclSupport = directoryInfo as IFileSystemAclSupport; + if (aclSupport == null) { - di.Create(directorySecurity); - } - else - { - directoryInfo.Create(); - directoryInfo.Extensibility.StoreMetadata("AccessControl:DirectorySecurity", - directorySecurity); + throw new NotSupportedException("The directory info does not support ACL extensions"); } + + directoryInfo.Create(); + aclSupport.SetAccessControl(directorySecurity); } #if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS @@ -40,12 +36,14 @@ public static class DirectoryInfoAclExtensions public static DirectorySecurity GetAccessControl( this IDirectoryInfo directoryInfo) { - IFileSystemExtensibility extensibility = - directoryInfo.Extensibility; - return extensibility.TryGetWrappedInstance(out DirectoryInfo di) - ? di.GetAccessControl() - : extensibility.RetrieveMetadata( - "AccessControl:DirectorySecurity") ?? new DirectorySecurity(); + IFileSystemAclSupport aclSupport = directoryInfo as IFileSystemAclSupport; + var value = aclSupport?.GetAccessControl(); + if (aclSupport == null || value is not DirectorySecurity directorySecurity) + { + throw new NotSupportedException("The directory info does not support ACL extensions"); + } + + return directorySecurity; } #if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS @@ -58,12 +56,14 @@ public static class DirectoryInfoAclExtensions this IDirectoryInfo directoryInfo, AccessControlSections includeSections) { - IFileSystemExtensibility extensibility = - directoryInfo.Extensibility; - return extensibility.TryGetWrappedInstance(out DirectoryInfo di) - ? di.GetAccessControl(includeSections) - : extensibility.RetrieveMetadata( - "AccessControl:DirectorySecurity") ?? new DirectorySecurity(); + IFileSystemAclSupport aclSupport = directoryInfo as IFileSystemAclSupport; + var value = aclSupport?.GetAccessControl((IFileSystemAclSupport.AccessControlSections) includeSections); + if (aclSupport == null || value is not DirectorySecurity directorySecurity) + { + throw new NotSupportedException("The directory info does not support ACL extensions"); + } + + return directorySecurity; } #if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS @@ -75,17 +75,13 @@ public static class DirectoryInfoAclExtensions public static void SetAccessControl(this IDirectoryInfo directoryInfo, DirectorySecurity directorySecurity) { - IFileSystemExtensibility extensibility = - directoryInfo.Extensibility; - if (extensibility.TryGetWrappedInstance(out DirectoryInfo di)) - { - di.SetAccessControl(directorySecurity); - } - else + IFileSystemAclSupport aclSupport = directoryInfo as IFileSystemAclSupport; + if (aclSupport == null) { - extensibility.StoreMetadata("AccessControl:DirectorySecurity", - directorySecurity); + throw new NotSupportedException("The directory info does not support ACL extensions"); } + + aclSupport.SetAccessControl(directorySecurity); } } } diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoWrapper.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoWrapper.cs index cb96e745e..ffb901ead 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoWrapper.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoWrapper.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.IO.Pipes; using System.Linq; using System.Runtime.Versioning; using System.Security.AccessControl; @@ -7,7 +8,7 @@ namespace System.IO.Abstractions { /// [Serializable] - public class DirectoryInfoWrapper : DirectoryInfoBase + public class DirectoryInfoWrapper : DirectoryInfoBase, IFileSystemAclSupport { private readonly DirectoryInfo instance; @@ -15,7 +16,6 @@ public class DirectoryInfoWrapper : DirectoryInfoBase public DirectoryInfoWrapper(IFileSystem fileSystem, DirectoryInfo instance) : base(fileSystem) { this.instance = instance ?? throw new ArgumentNullException(nameof(instance)); - this.Extensibility = new FileSystemExtensibility(instance); } #if FEATURE_CREATE_SYMBOLIC_LINK @@ -73,9 +73,6 @@ public override bool Exists get { return instance.Exists; } } - /// - public override IFileSystemExtensibility Extensibility { get; } - /// public override string Extension { @@ -335,5 +332,26 @@ public override string ToString() { return instance.ToString(); } + + /// + [SupportedOSPlatform("windows")] + public object GetAccessControl(IFileSystemAclSupport.AccessControlSections includeSections = IFileSystemAclSupport.AccessControlSections.Default) + { + return instance.GetAccessControl((AccessControlSections)includeSections); + } + + /// + [SupportedOSPlatform("windows")] + public void SetAccessControl(object value) + { + if (value is DirectorySecurity directorySecurity) + { + this.instance.SetAccessControl(directorySecurity); + } + else + { + throw new ArgumentException("value must be of type `FileSecurity`"); + } + } } } diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/FileAclExtensions.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/FileAclExtensions.cs index 8fb1657f1..805bca4df 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/FileAclExtensions.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/FileAclExtensions.cs @@ -18,12 +18,7 @@ public static class FileAclExtensions this IFile file, string path) { IFileInfo fileInfo = file.FileSystem.FileInfo.New(path); - IFileSystemExtensibility extensibility = - fileInfo.Extensibility; - return extensibility.TryGetWrappedInstance(out FileInfo fi) - ? fi.GetAccessControl() - : extensibility.RetrieveMetadata( - "AccessControl:FileSecurity") ?? new FileSecurity(); + return fileInfo.GetAccessControl(); } #if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS @@ -38,12 +33,7 @@ public static class FileAclExtensions AccessControlSections includeSections) { IFileInfo fileInfo = file.FileSystem.FileInfo.New(path); - IFileSystemExtensibility extensibility = - fileInfo.Extensibility; - return extensibility.TryGetWrappedInstance(out FileInfo fi) - ? fi.GetAccessControl(includeSections) - : extensibility.RetrieveMetadata( - "AccessControl:FileSecurity") ?? new FileSecurity(); + return fileInfo.GetAccessControl(includeSections); } #if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS @@ -57,17 +47,7 @@ public static class FileAclExtensions FileSecurity fileSecurity) { IFileInfo fileInfo = file.FileSystem.FileInfo.New(path); - IFileSystemExtensibility extensibility = - fileInfo.Extensibility; - if (extensibility.TryGetWrappedInstance(out FileInfo fi)) - { - fi.SetAccessControl(fileSecurity); - } - else - { - extensibility.StoreMetadata("AccessControl:FileSecurity", - fileSecurity); - } + fileInfo.SetAccessControl(fileSecurity); } } } diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoAclExtensions.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoAclExtensions.cs index e807b66e9..9ebf22eae 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoAclExtensions.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoAclExtensions.cs @@ -17,12 +17,14 @@ public static class FileInfoAclExtensions public static FileSecurity GetAccessControl( this IFileInfo fileInfo) { - IFileSystemExtensibility extensibility = - fileInfo.Extensibility; - return extensibility.TryGetWrappedInstance(out FileInfo fi) - ? fi.GetAccessControl() - : extensibility.RetrieveMetadata( - "AccessControl:FileSecurity") ?? new FileSecurity(); + IFileSystemAclSupport aclSupport = fileInfo as IFileSystemAclSupport; + var value = aclSupport?.GetAccessControl(); + if (aclSupport == null || value is not FileSecurity fileSecurity) + { + throw new NotSupportedException("The file info does not support ACL extensions"); + } + + return fileSecurity; } #if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS @@ -35,12 +37,14 @@ public static class FileInfoAclExtensions this IFileInfo fileInfo, AccessControlSections includeSections) { - IFileSystemExtensibility extensibility = - fileInfo.Extensibility; - return extensibility.TryGetWrappedInstance(out FileInfo fi) - ? fi.GetAccessControl(includeSections) - : extensibility.RetrieveMetadata( - "AccessControl:FileSecurity") ?? new FileSecurity(); + IFileSystemAclSupport aclSupport = fileInfo as IFileSystemAclSupport; + var value = aclSupport?.GetAccessControl((IFileSystemAclSupport.AccessControlSections)includeSections); + if (aclSupport == null || value is not FileSecurity fileSecurity) + { + throw new NotSupportedException("The file info does not support ACL extensions"); + } + + return fileSecurity; } #if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS @@ -52,17 +56,13 @@ public static class FileInfoAclExtensions public static void SetAccessControl(this IFileInfo fileInfo, FileSecurity fileSecurity) { - IFileSystemExtensibility extensibility = - fileInfo.Extensibility; - if (extensibility.TryGetWrappedInstance(out FileInfo fi)) - { - fi.SetAccessControl(fileSecurity); - } - else + IFileSystemAclSupport aclSupport = fileInfo as IFileSystemAclSupport; + if (aclSupport == null) { - extensibility.StoreMetadata("AccessControl:FileSecurity", - fileSecurity); + throw new NotSupportedException("The file info does not support ACL extensions"); } + + aclSupport.SetAccessControl(fileSecurity); } } } diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoWrapper.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoWrapper.cs index dbb3a230b..db31dd192 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoWrapper.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoWrapper.cs @@ -5,7 +5,7 @@ namespace System.IO.Abstractions { /// [Serializable] - public class FileInfoWrapper : FileInfoBase + public class FileInfoWrapper : FileInfoBase, IFileSystemAclSupport { private readonly FileInfo instance; @@ -13,7 +13,6 @@ public class FileInfoWrapper : FileInfoBase public FileInfoWrapper(IFileSystem fileSystem, FileInfo instance) : base(fileSystem) { this.instance = instance ?? throw new ArgumentNullException(nameof(instance)); - this.Extensibility = new FileSystemExtensibility(instance); } #if FEATURE_CREATE_SYMBOLIC_LINK @@ -71,9 +70,6 @@ public override bool Exists get { return instance.Exists; } } - /// - public override IFileSystemExtensibility Extensibility { get; } - /// public override string Extension { @@ -272,5 +268,26 @@ public override string ToString() { return instance.ToString(); } + + /// + [SupportedOSPlatform("windows")] + public object GetAccessControl(IFileSystemAclSupport.AccessControlSections includeSections = IFileSystemAclSupport.AccessControlSections.Default) + { + return instance.GetAccessControl((AccessControlSections)includeSections); + } + + /// + [SupportedOSPlatform("windows")] + public void SetAccessControl(object value) + { + if (value is FileSecurity fileSecurity) + { + this.instance.SetAccessControl(fileSecurity); + } + else + { + throw new ArgumentException("value must be of type `FileSecurity`"); + } + } } } diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/FileStreamAclExtensions.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/FileStreamAclExtensions.cs index 068860fc4..8da3aacfc 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/FileStreamAclExtensions.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/FileStreamAclExtensions.cs @@ -1,4 +1,5 @@ -using System.Runtime.Versioning; +using System.Reflection; +using System.Runtime.Versioning; using System.Security.AccessControl; namespace System.IO.Abstractions @@ -16,12 +17,14 @@ public static class FileStreamAclExtensions [SupportedOSPlatform("windows")] public static FileSecurity GetAccessControl(this FileSystemStream fileStream) { - IFileSystemExtensibility extensibility = - fileStream.Extensibility; - return extensibility.TryGetWrappedInstance(out FileStream fs) - ? fs.GetAccessControl() - : extensibility.RetrieveMetadata( - "AccessControl:FileSecurity") ?? new FileSecurity(); + IFileSystemAclSupport aclSupport = fileStream as IFileSystemAclSupport; + var value = aclSupport?.GetAccessControl(); + if (aclSupport == null || value is not FileSecurity fileSecurity) + { + throw new NotSupportedException("The file stream does not support ACL extensions"); + } + + return fileSecurity; } #if FEATURE_FILE_SYSTEM_ACL_EXTENSIONS @@ -33,17 +36,13 @@ public static FileSecurity GetAccessControl(this FileSystemStream fileStream) public static void SetAccessControl(this FileSystemStream fileStream, FileSecurity fileSecurity) { - IFileSystemExtensibility extensibility = - fileStream.Extensibility; - if (extensibility.TryGetWrappedInstance(out FileStream fs)) + IFileSystemAclSupport aclSupport = fileStream as IFileSystemAclSupport; + if (aclSupport == null) { - fs.SetAccessControl(fileSecurity); - } - else - { - extensibility.StoreMetadata("AccessControl:FileSecurity", - fileSecurity); + throw new NotSupportedException("The file info does not support ACL extensions"); } + + aclSupport.SetAccessControl(fileSecurity); } } } diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/FileStreamWrapper.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/FileStreamWrapper.cs index c80a5eab7..2dd0da9dc 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/FileStreamWrapper.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/FileStreamWrapper.cs @@ -1,15 +1,38 @@ -namespace System.IO.Abstractions +using System.Runtime.Versioning; +using System.Security.AccessControl; + +namespace System.IO.Abstractions { - internal sealed class FileStreamWrapper : FileSystemStream + internal sealed class FileStreamWrapper : FileSystemStream, IFileSystemAclSupport { + private readonly FileStream fileStream; + public FileStreamWrapper(FileStream fileStream) : base(fileStream, fileStream.Name, fileStream.IsAsync) { - Extensibility = new FileSystemExtensibility(fileStream); + this.fileStream = fileStream; } - /// - public override IFileSystemExtensibility Extensibility { get; } + /// + [SupportedOSPlatform("windows")] + public object GetAccessControl(IFileSystemAclSupport.AccessControlSections includeSections = IFileSystemAclSupport.AccessControlSections.Default) + { + return fileStream.GetAccessControl(); + } + + /// + [SupportedOSPlatform("windows")] + public void SetAccessControl(object value) + { + if (value is FileSecurity fileSecurity) + { + this.fileStream.SetAccessControl(fileSecurity); + } + else + { + throw new ArgumentException("value must be of type `FileSecurity`"); + } + } } } \ No newline at end of file diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/FileSystemExtensibility.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/FileSystemExtensibility.cs deleted file mode 100644 index 01cc59996..000000000 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/FileSystemExtensibility.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System.Collections.Generic; - -namespace System.IO.Abstractions -{ - internal class FileSystemExtensibility : IFileSystemExtensibility - { - private readonly object _wrappedInstance; - private readonly Dictionary _metadata = new(); - - public FileSystemExtensibility(object wrappedInstance) - { - _wrappedInstance = wrappedInstance; - } - - /// - public bool TryGetWrappedInstance(out T wrappedInstance) - { - if (_wrappedInstance is T value) - { - wrappedInstance = value; - return true; - } - - wrappedInstance = default; - return false; - } - - /// - public void StoreMetadata(string key, T value) - { - _metadata[key] = value; - } - - /// - public T RetrieveMetadata(string key) - { - if (_metadata.TryGetValue(key, out object value) && - value is T castedValue) - { - return castedValue; - } - - return default; - } - } -} \ No newline at end of file diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/FileSystemInfoBase.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/FileSystemInfoBase.cs index ce59dfc3c..7b265eb71 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/FileSystemInfoBase.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/FileSystemInfoBase.cs @@ -46,9 +46,6 @@ protected FileSystemInfoBase(IFileSystem fileSystem) /// public abstract bool Exists { get; } - /// - public abstract IFileSystemExtensibility Extensibility { get; } - /// public abstract string Extension { get; } diff --git a/src/TestableIO.System.IO.Abstractions/FileSystemStream.cs b/src/TestableIO.System.IO.Abstractions/FileSystemStream.cs index becc41d65..839986a75 100644 --- a/src/TestableIO.System.IO.Abstractions/FileSystemStream.cs +++ b/src/TestableIO.System.IO.Abstractions/FileSystemStream.cs @@ -24,11 +24,6 @@ public override bool CanTimeout public override bool CanWrite => _stream.CanWrite; - /// - /// A container to support extensions on. - /// - public abstract IFileSystemExtensibility Extensibility { get; } - /// public bool IsAsync { get; } diff --git a/src/TestableIO.System.IO.Abstractions/IFileSystemAclSupport.cs b/src/TestableIO.System.IO.Abstractions/IFileSystemAclSupport.cs new file mode 100644 index 000000000..f8c156a15 --- /dev/null +++ b/src/TestableIO.System.IO.Abstractions/IFileSystemAclSupport.cs @@ -0,0 +1,63 @@ +using System.Runtime.Versioning; + +namespace System.IO.Abstractions +{ + /// + /// Support ACL functionality on file system instances. + /// + public interface IFileSystemAclSupport + { + /// + /// Retrieves previously stored access control information. + /// + [SupportedOSPlatform("windows")] + object GetAccessControl(AccessControlSections includeSections = AccessControlSections.Default); + + /// + /// Stores access control information. + /// + [SupportedOSPlatform("windows")] + void SetAccessControl(object value); + + /// + /// Specifies which sections of a security descriptor to save or load. + [Flags] + public enum AccessControlSections + { + /// + /// No sections. + /// + None = 0, + + /// + /// The system access control list (SACL). + /// + Audit = 1, + + /// + /// The discretionary access control list (DACL). + /// + Access = 2, + + /// + /// The owner. + /// + Owner = 4, + + /// + /// The primary group. + /// + Group = 8, + + /// + /// The entire security descriptor. + /// + All = Group | Owner | Access | Audit, + + /// + /// The default value when no are specified.# + /// + Default = Access | Owner | Group, + } + } +} \ No newline at end of file diff --git a/src/TestableIO.System.IO.Abstractions/IFileSystemExtensibility.cs b/src/TestableIO.System.IO.Abstractions/IFileSystemExtensibility.cs deleted file mode 100644 index f8d6b86c3..000000000 --- a/src/TestableIO.System.IO.Abstractions/IFileSystemExtensibility.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System.Diagnostics.CodeAnalysis; - -namespace System.IO.Abstractions -{ - /// - /// A container to give access to the wrapped instance and to store metadata on entities. - ///
- /// This is useful for writing extension methods. - ///
- public interface IFileSystemExtensibility - { - /// - /// The wrapped instance on a real file system. - /// - /// - /// when not on a real file system or if the requested type does not match, - /// otherwise the wrapped instance. - /// - bool TryGetWrappedInstance([NotNullWhen(true)] out T? wrappedInstance); - - /// - /// Stores additional metadata to the . - /// - /// The type of the value to store. - /// The key under which to store the metadata. - /// The value to store under the given . - void StoreMetadata(string key, T? value); - - /// - /// Retrieves a previously stored metadata on the . - /// - /// The type of the value to retrieve. - /// The key under which the metadata was stored. - /// The value of the previously stored metadata, or . - T? RetrieveMetadata(string key); - } -} diff --git a/src/TestableIO.System.IO.Abstractions/IFileSystemInfo.cs b/src/TestableIO.System.IO.Abstractions/IFileSystemInfo.cs index b1208c26a..68e6a25ee 100644 --- a/src/TestableIO.System.IO.Abstractions/IFileSystemInfo.cs +++ b/src/TestableIO.System.IO.Abstractions/IFileSystemInfo.cs @@ -20,11 +20,6 @@ public interface IFileSystemInfo /// bool Exists { get; } - /// - /// A container to support extensions on . - /// - IFileSystemExtensibility Extensibility { get; } - /// string Extension { get; } diff --git a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.DirectoryInfo_.NET 5.0.snap b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.DirectoryInfo_.NET 5.0.snap index e88780a62..c986824b9 100644 --- a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.DirectoryInfo_.NET 5.0.snap +++ b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.DirectoryInfo_.NET 5.0.snap @@ -1,8 +1,5 @@ { - "ExtraMembers": [ - "System.IO.Abstractions.IFileSystemExtensibility Extensibility", - "System.IO.Abstractions.IFileSystemExtensibility get_Extensibility()" - ], + "ExtraMembers": [], "MissingMembers": [ "System.Object GetLifetimeService()", "System.Object InitializeLifetimeService()", diff --git a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.DirectoryInfo_.NET 6.0.snap b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.DirectoryInfo_.NET 6.0.snap index e88780a62..c986824b9 100644 --- a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.DirectoryInfo_.NET 6.0.snap +++ b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.DirectoryInfo_.NET 6.0.snap @@ -1,8 +1,5 @@ { - "ExtraMembers": [ - "System.IO.Abstractions.IFileSystemExtensibility Extensibility", - "System.IO.Abstractions.IFileSystemExtensibility get_Extensibility()" - ], + "ExtraMembers": [], "MissingMembers": [ "System.Object GetLifetimeService()", "System.Object InitializeLifetimeService()", diff --git a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.DirectoryInfo_.NET Core 3.1.snap b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.DirectoryInfo_.NET Core 3.1.snap index e88780a62..c986824b9 100644 --- a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.DirectoryInfo_.NET Core 3.1.snap +++ b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.DirectoryInfo_.NET Core 3.1.snap @@ -1,8 +1,5 @@ { - "ExtraMembers": [ - "System.IO.Abstractions.IFileSystemExtensibility Extensibility", - "System.IO.Abstractions.IFileSystemExtensibility get_Extensibility()" - ], + "ExtraMembers": [], "MissingMembers": [ "System.Object GetLifetimeService()", "System.Object InitializeLifetimeService()", diff --git a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.DirectoryInfo_.NET Framework 4.6.1.snap b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.DirectoryInfo_.NET Framework 4.6.1.snap index ee92992d2..ec21e0f76 100644 --- a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.DirectoryInfo_.NET Framework 4.6.1.snap +++ b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.DirectoryInfo_.NET Framework 4.6.1.snap @@ -1,8 +1,5 @@ { - "ExtraMembers": [ - "System.IO.Abstractions.IFileSystemExtensibility Extensibility", - "System.IO.Abstractions.IFileSystemExtensibility get_Extensibility()" - ], + "ExtraMembers": [], "MissingMembers": [ "System.IO.Abstractions.IDirectoryInfo CreateSubdirectory(System.String, System.Security.AccessControl.DirectorySecurity)", "System.Object GetLifetimeService()", diff --git a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.FileInfo_.NET 5.0.snap b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.FileInfo_.NET 5.0.snap index e88780a62..c986824b9 100644 --- a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.FileInfo_.NET 5.0.snap +++ b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.FileInfo_.NET 5.0.snap @@ -1,8 +1,5 @@ { - "ExtraMembers": [ - "System.IO.Abstractions.IFileSystemExtensibility Extensibility", - "System.IO.Abstractions.IFileSystemExtensibility get_Extensibility()" - ], + "ExtraMembers": [], "MissingMembers": [ "System.Object GetLifetimeService()", "System.Object InitializeLifetimeService()", diff --git a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.FileInfo_.NET 6.0.snap b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.FileInfo_.NET 6.0.snap index e88780a62..c986824b9 100644 --- a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.FileInfo_.NET 6.0.snap +++ b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.FileInfo_.NET 6.0.snap @@ -1,8 +1,5 @@ { - "ExtraMembers": [ - "System.IO.Abstractions.IFileSystemExtensibility Extensibility", - "System.IO.Abstractions.IFileSystemExtensibility get_Extensibility()" - ], + "ExtraMembers": [], "MissingMembers": [ "System.Object GetLifetimeService()", "System.Object InitializeLifetimeService()", diff --git a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.FileInfo_.NET Core 3.1.snap b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.FileInfo_.NET Core 3.1.snap index 816ad5ef5..504fba3c8 100644 --- a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.FileInfo_.NET Core 3.1.snap +++ b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.FileInfo_.NET Core 3.1.snap @@ -1,8 +1,5 @@ { - "ExtraMembers": [ - "System.IO.Abstractions.IFileSystemExtensibility Extensibility", - "System.IO.Abstractions.IFileSystemExtensibility get_Extensibility()" - ], + "ExtraMembers": [], "MissingMembers": [ "System.Object GetLifetimeService()", "System.Object InitializeLifetimeService()", diff --git a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.FileInfo_.NET Framework 4.6.1.snap b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.FileInfo_.NET Framework 4.6.1.snap index 3fd5a58e5..edd9281da 100644 --- a/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.FileInfo_.NET Framework 4.6.1.snap +++ b/tests/TestableIO.System.IO.Abstractions.Wrappers.Tests/__snapshots__/ApiParityTests.FileInfo_.NET Framework 4.6.1.snap @@ -1,8 +1,5 @@ { - "ExtraMembers": [ - "System.IO.Abstractions.IFileSystemExtensibility Extensibility", - "System.IO.Abstractions.IFileSystemExtensibility get_Extensibility()" - ], + "ExtraMembers": [], "MissingMembers": [ "System.Object GetLifetimeService()", "System.Object InitializeLifetimeService()", From 83b58176400a3181bea3b207761842d2b225d385 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Wed, 23 Nov 2022 08:50:53 +0100 Subject: [PATCH 20/25] Cleanup changed code --- .../FileSystemExtensibility.cs | 26 ------------------- .../MockDirectoryInfo.cs | 9 ++++++- .../MockFileInfo.cs | 9 ++++++- .../MockFileStream.cs | 21 ++++++++++----- .../DirectoryInfoWrapper.cs | 9 ++++++- .../FileInfoWrapper.cs | 9 ++++++- .../FileStreamWrapper.cs | 11 ++++++-- .../IFileSystemAclSupport.cs | 20 +++++++------- 8 files changed, 66 insertions(+), 48 deletions(-) diff --git a/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs b/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs index 099dbb990..a840574ed 100644 --- a/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs +++ b/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs @@ -28,31 +28,5 @@ internal void CloneFrom(FileSystemExtensibility template) _metadata[item.Key] = item.Value; } } - - public static FileSystemExtensibility GetNullObject(Func exceptionFactory) - => new NullFileSystemExtensibility(exceptionFactory); - - private sealed class NullFileSystemExtensibility : FileSystemExtensibility - { - private readonly Func _exceptionFactory; - - public NullFileSystemExtensibility(Func exceptionFactory) - { - _exceptionFactory = exceptionFactory; - } - - public override void StoreMetadata(string key, object value) - { - _ = key; - _ = value; - throw _exceptionFactory.Invoke(); - } - - public override object RetrieveMetadata(string key) - { - _ = key; - throw _exceptionFactory.Invoke(); - } - } } } \ No newline at end of file diff --git a/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs b/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs index 4b444a8b9..592013a06 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs @@ -421,9 +421,16 @@ public override string ToString() return originalPath; } + /// + [SupportedOSPlatform("windows")] + public object GetAccessControl() + { + return GetMockDirectoryData().AccessControl; + } + /// [SupportedOSPlatform("windows")] - public object GetAccessControl(IFileSystemAclSupport.AccessControlSections includeSections = IFileSystemAclSupport.AccessControlSections.Default) + public object GetAccessControl(IFileSystemAclSupport.AccessControlSections includeSections) { return GetMockDirectoryData().AccessControl; } diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs b/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs index 83ffee41d..bdf0580ea 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs @@ -384,9 +384,16 @@ public override string ToString() return originalPath; } + /// + [SupportedOSPlatform("windows")] + public object GetAccessControl() + { + return GetMockFileData().AccessControl; + } + /// [SupportedOSPlatform("windows")] - public object GetAccessControl(IFileSystemAclSupport.AccessControlSections includeSections = IFileSystemAclSupport.AccessControlSections.Default) + public object GetAccessControl(IFileSystemAclSupport.AccessControlSections includeSections) { return GetMockFileData().AccessControl; } diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFileStream.cs b/src/System.IO.Abstractions.TestingHelpers/MockFileStream.cs index dff4a17bb..adcb4ac0e 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFileStream.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFileStream.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using System.Threading; using System.Runtime.Versioning; +using System.Security.AccessControl; namespace System.IO.Abstractions.TestingHelpers { @@ -197,25 +198,31 @@ public override void Flush() InternalFlush(); } + /// + [SupportedOSPlatform("windows")] + public object GetAccessControl() + { + return GetMockFileData().AccessControl; + } + /// [SupportedOSPlatform("windows")] - public object GetAccessControl(IFileSystemAclSupport.AccessControlSections includeSections = IFileSystemAclSupport.AccessControlSections.Default) + public object GetAccessControl(IFileSystemAclSupport.AccessControlSections includeSections) { - return GetExtensibility().RetrieveMetadata("AccessControl:FileSecurity"); + return GetMockFileData().AccessControl; } /// [SupportedOSPlatform("windows")] public void SetAccessControl(object value) { - GetExtensibility().StoreMetadata("AccessControl:FileSecurity", value); + GetMockFileData().AccessControl = value as FileSecurity; } - private FileSystemExtensibility GetExtensibility() + private MockFileData GetMockFileData() { - var mockFileData = mockFileDataAccessor.GetFile(path); - return mockFileData?.Extensibility ?? FileSystemExtensibility.GetNullObject( - () => CommonExceptions.FileNotFound(path)); + return mockFileDataAccessor.GetFile(path) + ?? throw CommonExceptions.FileNotFound(path); } private void InternalFlush() diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoWrapper.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoWrapper.cs index ffb901ead..04cba0a23 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoWrapper.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoWrapper.cs @@ -333,9 +333,16 @@ public override string ToString() return instance.ToString(); } + /// + [SupportedOSPlatform("windows")] + public object GetAccessControl() + { + return instance.GetAccessControl(); + } + /// [SupportedOSPlatform("windows")] - public object GetAccessControl(IFileSystemAclSupport.AccessControlSections includeSections = IFileSystemAclSupport.AccessControlSections.Default) + public object GetAccessControl(IFileSystemAclSupport.AccessControlSections includeSections) { return instance.GetAccessControl((AccessControlSections)includeSections); } diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoWrapper.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoWrapper.cs index db31dd192..7d70f9a2e 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoWrapper.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoWrapper.cs @@ -269,9 +269,16 @@ public override string ToString() return instance.ToString(); } + /// + [SupportedOSPlatform("windows")] + public object GetAccessControl() + { + return instance.GetAccessControl(); + } + /// [SupportedOSPlatform("windows")] - public object GetAccessControl(IFileSystemAclSupport.AccessControlSections includeSections = IFileSystemAclSupport.AccessControlSections.Default) + public object GetAccessControl(IFileSystemAclSupport.AccessControlSections includeSections) { return instance.GetAccessControl((AccessControlSections)includeSections); } diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/FileStreamWrapper.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/FileStreamWrapper.cs index 2dd0da9dc..1096c36aa 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/FileStreamWrapper.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/FileStreamWrapper.cs @@ -14,13 +14,20 @@ public FileStreamWrapper(FileStream fileStream) this.fileStream = fileStream; } - /// + /// [SupportedOSPlatform("windows")] - public object GetAccessControl(IFileSystemAclSupport.AccessControlSections includeSections = IFileSystemAclSupport.AccessControlSections.Default) + public object GetAccessControl() { return fileStream.GetAccessControl(); } + /// + [SupportedOSPlatform("windows")] + public object GetAccessControl(IFileSystemAclSupport.AccessControlSections includeSections) + { + throw new NotSupportedException("GetAccessControl with includeSections is not supported for FileStreams"); + } + /// [SupportedOSPlatform("windows")] public void SetAccessControl(object value) diff --git a/src/TestableIO.System.IO.Abstractions/IFileSystemAclSupport.cs b/src/TestableIO.System.IO.Abstractions/IFileSystemAclSupport.cs index f8c156a15..b7d05715c 100644 --- a/src/TestableIO.System.IO.Abstractions/IFileSystemAclSupport.cs +++ b/src/TestableIO.System.IO.Abstractions/IFileSystemAclSupport.cs @@ -8,13 +8,20 @@ namespace System.IO.Abstractions public interface IFileSystemAclSupport { /// - /// Retrieves previously stored access control information. + /// Gets a access control object that encapsulates the access control list (ACL) entries for the file or directory in the file system. /// [SupportedOSPlatform("windows")] - object GetAccessControl(AccessControlSections includeSections = AccessControlSections.Default); + object GetAccessControl(); /// - /// Stores access control information. + /// Gets a access control object that encapsulates the access control list (ACL) entries for the file or directory in the file system. + /// + /// One of the values that specifies the type of access control list (ACL) information to receive. + [SupportedOSPlatform("windows")] + object GetAccessControl(AccessControlSections includeSections); + + /// + /// Applies access control list (ACL) entries described by the object to the file or directory in the file system. /// [SupportedOSPlatform("windows")] void SetAccessControl(object value); @@ -52,12 +59,7 @@ public enum AccessControlSections /// /// The entire security descriptor. /// - All = Group | Owner | Access | Audit, - - /// - /// The default value when no are specified.# - /// - Default = Access | Owner | Group, + All = Group | Owner | Access | Audit } } } \ No newline at end of file From 84290ceef4f0f4d2fe45390ef9a9078e4e5b8c3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Fri, 25 Nov 2022 09:04:19 +0100 Subject: [PATCH 21/25] Implement review findings from @siprbaum --- .../FileSystemExtensibility.cs | 2 +- .../MockDirectoryData.cs | 4 ++-- .../MockDirectoryInfo.cs | 2 +- src/System.IO.Abstractions.TestingHelpers/MockFileData.cs | 6 +++--- .../DirectoryInfoAclExtensions.cs | 8 ++++---- .../FileInfoAclExtensions.cs | 8 ++++---- .../FileStreamAclExtensions.cs | 4 ++-- 7 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs b/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs index a840574ed..08bf4390a 100644 --- a/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs +++ b/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs @@ -21,7 +21,7 @@ public virtual object RetrieveMetadata(string key) return default; } - internal void CloneFrom(FileSystemExtensibility template) + internal void CopyMetadataFrom(FileSystemExtensibility template) { foreach (var item in template._metadata) { diff --git a/src/System.IO.Abstractions.TestingHelpers/MockDirectoryData.cs b/src/System.IO.Abstractions.TestingHelpers/MockDirectoryData.cs index 41103f2d7..1481bdf98 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockDirectoryData.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockDirectoryData.cs @@ -21,8 +21,8 @@ public new DirectorySecurity AccessControl { // DirectorySecurity's constructor will throw PlatformNotSupportedException on non-Windows platform, so we initialize it in lazy way. // This let's us use this class as long as we don't use AccessControl property. - var value = Extensibility.RetrieveMetadata("AccessControl:DirectorySecurity"); - if (value is not DirectorySecurity directorySecurity) + var directorySecurity = Extensibility.RetrieveMetadata("AccessControl:DirectorySecurity") as DirectorySecurity; + if (directorySecurity == null) { directorySecurity = new DirectorySecurity(); Extensibility.StoreMetadata("AccessControl:DirectorySecurity", directorySecurity); diff --git a/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs b/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs index 592013a06..e9d9cf140 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs @@ -27,7 +27,7 @@ public MockDirectoryInfo(IMockFileDataAccessor mockFileDataAccessor, string dire { this.mockFileDataAccessor = mockFileDataAccessor ?? throw new ArgumentNullException(nameof(mockFileDataAccessor)); - if (directoryPath== null) + if (directoryPath == null) { throw new ArgumentNullException("path", StringResources.Manager.GetString("VALUE_CANNOT_BE_NULL")); } diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs b/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs index 42792b6f7..939cb1ff8 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs @@ -102,7 +102,7 @@ public MockFileData(MockFileData template) throw new ArgumentNullException(nameof(template)); } - extensibility.CloneFrom(template.extensibility); + extensibility.CopyMetadataFrom(template.extensibility); Attributes = template.Attributes; Contents = template.Contents.ToArray(); CreationTime = template.CreationTime; @@ -191,8 +191,8 @@ public FileSecurity AccessControl { // FileSecurity's constructor will throw PlatformNotSupportedException on non-Windows platform, so we initialize it in lazy way. // This let's us use this class as long as we don't use AccessControl property. - var value = Extensibility.RetrieveMetadata("AccessControl:FileSecurity"); - if (value is not FileSecurity fileSecurity) + var fileSecurity = Extensibility.RetrieveMetadata("AccessControl:FileSecurity") as FileSecurity; + if (fileSecurity == null) { fileSecurity = new FileSecurity(); Extensibility.StoreMetadata("AccessControl:FileSecurity", fileSecurity); diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoAclExtensions.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoAclExtensions.cs index eacfd4489..743ff7545 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoAclExtensions.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/DirectoryInfoAclExtensions.cs @@ -37,8 +37,8 @@ public static class DirectoryInfoAclExtensions this IDirectoryInfo directoryInfo) { IFileSystemAclSupport aclSupport = directoryInfo as IFileSystemAclSupport; - var value = aclSupport?.GetAccessControl(); - if (aclSupport == null || value is not DirectorySecurity directorySecurity) + var directorySecurity = aclSupport?.GetAccessControl() as DirectorySecurity; + if (aclSupport == null || directorySecurity == null) { throw new NotSupportedException("The directory info does not support ACL extensions"); } @@ -57,8 +57,8 @@ public static class DirectoryInfoAclExtensions AccessControlSections includeSections) { IFileSystemAclSupport aclSupport = directoryInfo as IFileSystemAclSupport; - var value = aclSupport?.GetAccessControl((IFileSystemAclSupport.AccessControlSections) includeSections); - if (aclSupport == null || value is not DirectorySecurity directorySecurity) + var directorySecurity = aclSupport?.GetAccessControl((IFileSystemAclSupport.AccessControlSections) includeSections) as DirectorySecurity; + if (aclSupport == null || directorySecurity == null) { throw new NotSupportedException("The directory info does not support ACL extensions"); } diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoAclExtensions.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoAclExtensions.cs index 9ebf22eae..69eb53942 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoAclExtensions.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/FileInfoAclExtensions.cs @@ -18,8 +18,8 @@ public static class FileInfoAclExtensions this IFileInfo fileInfo) { IFileSystemAclSupport aclSupport = fileInfo as IFileSystemAclSupport; - var value = aclSupport?.GetAccessControl(); - if (aclSupport == null || value is not FileSecurity fileSecurity) + var fileSecurity = aclSupport?.GetAccessControl() as FileSecurity; + if (aclSupport == null || fileSecurity == null) { throw new NotSupportedException("The file info does not support ACL extensions"); } @@ -38,8 +38,8 @@ public static class FileInfoAclExtensions AccessControlSections includeSections) { IFileSystemAclSupport aclSupport = fileInfo as IFileSystemAclSupport; - var value = aclSupport?.GetAccessControl((IFileSystemAclSupport.AccessControlSections)includeSections); - if (aclSupport == null || value is not FileSecurity fileSecurity) + var fileSecurity = aclSupport?.GetAccessControl((IFileSystemAclSupport.AccessControlSections)includeSections) as FileSecurity; + if (aclSupport == null || fileSecurity == null) { throw new NotSupportedException("The file info does not support ACL extensions"); } diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/FileStreamAclExtensions.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/FileStreamAclExtensions.cs index 8da3aacfc..958e54ccc 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/FileStreamAclExtensions.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/FileStreamAclExtensions.cs @@ -18,8 +18,8 @@ public static class FileStreamAclExtensions public static FileSecurity GetAccessControl(this FileSystemStream fileStream) { IFileSystemAclSupport aclSupport = fileStream as IFileSystemAclSupport; - var value = aclSupport?.GetAccessControl(); - if (aclSupport == null || value is not FileSecurity fileSecurity) + var fileSecurity = aclSupport?.GetAccessControl() as FileSecurity; + if (aclSupport == null || fileSecurity == null) { throw new NotSupportedException("The file stream does not support ACL extensions"); } From cb8cf448bf8e993a75e017e77ad35ac127160432 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Mon, 28 Nov 2022 20:39:04 +0100 Subject: [PATCH 22/25] Fix merge error --- .../FileSystemExtensibility.cs | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/TestableIO.System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs diff --git a/src/TestableIO.System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs b/src/TestableIO.System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs new file mode 100644 index 000000000..6f92133cc --- /dev/null +++ b/src/TestableIO.System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs @@ -0,0 +1,32 @@ +using System.Collections.Generic; + +namespace System.IO.Abstractions.TestingHelpers +{ + internal class FileSystemExtensibility + { + private readonly Dictionary _metadata = new(); + + public virtual void StoreMetadata(string key, object value) + { + _metadata[key] = value; + } + + public virtual object RetrieveMetadata(string key) + { + if (_metadata.TryGetValue(key, out object value)) + { + return value; + } + + return default; + } + + internal void CopyMetadataFrom(FileSystemExtensibility template) + { + foreach (var item in template._metadata) + { + _metadata[item.Key] = item.Value; + } + } + } +} \ No newline at end of file From a5221446e4ace12a98a2ed49373493035737d1f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Fri, 2 Dec 2022 12:40:09 +0100 Subject: [PATCH 23/25] Implement review comments --- .../FileSystemExtensibility.cs | 32 ------------------- .../MockDirectoryData.cs | 15 ++++----- .../MockFileData.cs | 24 ++++---------- .../IFileSystemAclSupport.cs | 7 +--- 4 files changed, 14 insertions(+), 64 deletions(-) delete mode 100644 src/TestableIO.System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs diff --git a/src/TestableIO.System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs b/src/TestableIO.System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs deleted file mode 100644 index 6f92133cc..000000000 --- a/src/TestableIO.System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Collections.Generic; - -namespace System.IO.Abstractions.TestingHelpers -{ - internal class FileSystemExtensibility - { - private readonly Dictionary _metadata = new(); - - public virtual void StoreMetadata(string key, object value) - { - _metadata[key] = value; - } - - public virtual object RetrieveMetadata(string key) - { - if (_metadata.TryGetValue(key, out object value)) - { - return value; - } - - return default; - } - - internal void CopyMetadataFrom(FileSystemExtensibility template) - { - foreach (var item in template._metadata) - { - _metadata[item.Key] = item.Value; - } - } - } -} \ No newline at end of file diff --git a/src/TestableIO.System.IO.Abstractions.TestingHelpers/MockDirectoryData.cs b/src/TestableIO.System.IO.Abstractions.TestingHelpers/MockDirectoryData.cs index 1481bdf98..28d8925f1 100644 --- a/src/TestableIO.System.IO.Abstractions.TestingHelpers/MockDirectoryData.cs +++ b/src/TestableIO.System.IO.Abstractions.TestingHelpers/MockDirectoryData.cs @@ -7,6 +7,10 @@ namespace System.IO.Abstractions.TestingHelpers [Serializable] public class MockDirectoryData : MockFileData { + + [NonSerialized] + private DirectorySecurity accessControl; + /// public MockDirectoryData() : base(string.Empty) { @@ -21,16 +25,9 @@ public new DirectorySecurity AccessControl { // DirectorySecurity's constructor will throw PlatformNotSupportedException on non-Windows platform, so we initialize it in lazy way. // This let's us use this class as long as we don't use AccessControl property. - var directorySecurity = Extensibility.RetrieveMetadata("AccessControl:DirectorySecurity") as DirectorySecurity; - if (directorySecurity == null) - { - directorySecurity = new DirectorySecurity(); - Extensibility.StoreMetadata("AccessControl:DirectorySecurity", directorySecurity); - } - - return directorySecurity; + return accessControl ?? (accessControl = new DirectorySecurity()); } - set { Extensibility.StoreMetadata("AccessControl:DirectorySecurity", value); } + set { accessControl = value; } } } } \ No newline at end of file diff --git a/src/TestableIO.System.IO.Abstractions.TestingHelpers/MockFileData.cs b/src/TestableIO.System.IO.Abstractions.TestingHelpers/MockFileData.cs index 939cb1ff8..be7c88667 100644 --- a/src/TestableIO.System.IO.Abstractions.TestingHelpers/MockFileData.cs +++ b/src/TestableIO.System.IO.Abstractions.TestingHelpers/MockFileData.cs @@ -34,13 +34,10 @@ public class MockFileData public static readonly DateTimeOffset DefaultDateTimeOffset = new DateTime(1601, 01, 01, 00, 00, 00, DateTimeKind.Utc); /// - /// The extensibility of the . + /// The access control of the . /// - internal FileSystemExtensibility Extensibility - => extensibility; - [NonSerialized] - private FileSystemExtensibility extensibility = new FileSystemExtensibility(); + private FileSecurity accessControl; /// /// Gets a value indicating whether the is a directory or not. @@ -101,8 +98,8 @@ public MockFileData(MockFileData template) { throw new ArgumentNullException(nameof(template)); } - - extensibility.CopyMetadataFrom(template.extensibility); + + accessControl = template.accessControl; Attributes = template.Attributes; Contents = template.Contents.ToArray(); CreationTime = template.CreationTime; @@ -136,7 +133,7 @@ public string TextContents public DateTimeOffset CreationTime { get { return creationTime; } - set{ creationTime = value.ToUniversalTime(); } + set { creationTime = value.ToUniversalTime(); } } private DateTimeOffset creationTime; @@ -191,16 +188,9 @@ public FileSecurity AccessControl { // FileSecurity's constructor will throw PlatformNotSupportedException on non-Windows platform, so we initialize it in lazy way. // This let's us use this class as long as we don't use AccessControl property. - var fileSecurity = Extensibility.RetrieveMetadata("AccessControl:FileSecurity") as FileSecurity; - if (fileSecurity == null) - { - fileSecurity = new FileSecurity(); - Extensibility.StoreMetadata("AccessControl:FileSecurity", fileSecurity); - } - - return fileSecurity; + return accessControl ?? (accessControl = new FileSecurity()); } - set { Extensibility.StoreMetadata("AccessControl:FileSecurity", value); } + set { accessControl = value; } } /// diff --git a/src/TestableIO.System.IO.Abstractions/IFileSystemAclSupport.cs b/src/TestableIO.System.IO.Abstractions/IFileSystemAclSupport.cs index b7d05715c..e1f6079b0 100644 --- a/src/TestableIO.System.IO.Abstractions/IFileSystemAclSupport.cs +++ b/src/TestableIO.System.IO.Abstractions/IFileSystemAclSupport.cs @@ -1,6 +1,4 @@ -using System.Runtime.Versioning; - -namespace System.IO.Abstractions +namespace System.IO.Abstractions { /// /// Support ACL functionality on file system instances. @@ -10,20 +8,17 @@ public interface IFileSystemAclSupport /// /// Gets a access control object that encapsulates the access control list (ACL) entries for the file or directory in the file system. /// - [SupportedOSPlatform("windows")] object GetAccessControl(); /// /// Gets a access control object that encapsulates the access control list (ACL) entries for the file or directory in the file system. /// /// One of the values that specifies the type of access control list (ACL) information to receive. - [SupportedOSPlatform("windows")] object GetAccessControl(AccessControlSections includeSections); /// /// Applies access control list (ACL) entries described by the object to the file or directory in the file system. /// - [SupportedOSPlatform("windows")] void SetAccessControl(object value); /// From b8e701c1f9fe084f7adf852c0e3950ba88a085aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Fri, 2 Dec 2022 12:41:28 +0100 Subject: [PATCH 24/25] Bump major version to 19.0 --- version.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.json b/version.json index 4abc70c44..0999bd51e 100644 --- a/version.json +++ b/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/AArnott/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", - "version": "18.0", + "version": "19.0", "assemblyVersion": { "precision": "major" }, From cbaf4cca8daec91bb5a986a8c235123e08097a6a Mon Sep 17 00:00:00 2001 From: Florian Greinacher Date: Thu, 8 Dec 2022 22:04:22 +0100 Subject: [PATCH 25/25] refactor: delete extra file --- .../FileSystemExtensibility.cs | 32 ------------------- 1 file changed, 32 deletions(-) delete mode 100644 src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs diff --git a/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs b/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs deleted file mode 100644 index 08bf4390a..000000000 --- a/src/System.IO.Abstractions.TestingHelpers/FileSystemExtensibility.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Collections.Generic; - -namespace System.IO.Abstractions.TestingHelpers -{ - internal class FileSystemExtensibility - { - private readonly Dictionary _metadata = new(); - - public virtual void StoreMetadata(string key, object value) - { - _metadata[key] = value; - } - - public virtual object RetrieveMetadata(string key) - { - if (_metadata.TryGetValue(key, out object value)) - { - return value; - } - - return default; - } - - internal void CopyMetadataFrom(FileSystemExtensibility template) - { - foreach (var item in template._metadata) - { - _metadata[item.Key] = item.Value; - } - } - } -} \ No newline at end of file