Add missing TarFile.CreateFromDirectoryAsync roundtrip tests. (#84303)
authorCarlos Sánchez López <1175054+carlossanlop@users.noreply.github.com>
Fri, 14 Apr 2023 19:41:31 +0000 (12:41 -0700)
committerGitHub <noreply@github.com>
Fri, 14 Apr 2023 19:41:31 +0000 (13:41 -0600)
src/libraries/System.Formats.Tar/tests/System.Formats.Tar.Tests.csproj
src/libraries/System.Formats.Tar/tests/TarFile/TarFile.CreateFromDirectoryAsync.File.Roundtrip.cs [new file with mode: 0644]

index 1be774fa1f487a2ab45c650053361d740abf5109..ac75d0d7416db32bc3726a41f2663d42adda8439 100644 (file)
@@ -13,6 +13,7 @@
     <Compile Include="SimulatedDataStream.cs" />
     <Compile Include="TarEntry\TarEntry.ExtractToFile.Tests.cs" />
     <Compile Include="TarEntry\TarEntry.ExtractToFileAsync.Tests.cs" />
+    <Compile Include="TarFile\TarFile.CreateFromDirectoryAsync.File.Roundtrip.cs" />
     <Compile Include="TarFile\TarFile.ExtractToDirectoryAsync.Stream.Tests.cs" />
     <Compile Include="TarFile\TarFile.ExtractToDirectoryAsync.File.Tests.cs" />
     <Compile Include="TarFile\TarFile.CreateFromDirectoryAsync.Stream.Tests.cs" />
diff --git a/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.CreateFromDirectoryAsync.File.Roundtrip.cs b/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.CreateFromDirectoryAsync.File.Roundtrip.cs
new file mode 100644 (file)
index 0000000..7908d45
--- /dev/null
@@ -0,0 +1,80 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.IO;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace System.Formats.Tar.Tests
+{
+    public class TarFile_CreateFromDirectoryAsync_Roundtrip_Tests : TarTestsBase
+    {
+        [ConditionalTheory(typeof(MountHelper), nameof(MountHelper.CanCreateSymbolicLinks))]
+        [InlineData("./file.txt", "subDirectory")]
+        [InlineData("../file.txt", "subDirectory")]
+        [InlineData("../file.txt", "subDirectory1/subDirectory1.1")]
+        [InlineData("./file.txt", "subDirectory1/subDirectory1.1")]
+        [InlineData("./file.txt", null)]
+        public async Task SymlinkRelativeTargets_InsideTheArchive_RoundtripsSuccessfully_Async(string symlinkTargetPath, string subDirectory)
+        {
+            using TempDirectory root = new TempDirectory();
+
+            string destinationArchive = Path.Join(root.Path, "destination.tar");
+
+            string sourceDirectoryName = Path.Join(root.Path, "baseDirectory");
+            Directory.CreateDirectory(sourceDirectoryName);
+
+            string destinationDirectoryName = Path.Join(root.Path, "destinationDirectory");
+            Directory.CreateDirectory(destinationDirectoryName);
+
+            string sourceSubDirectory = Path.Join(sourceDirectoryName, subDirectory);
+            if (subDirectory != null) Directory.CreateDirectory(sourceSubDirectory);
+
+            File.Create(Path.Join(sourceDirectoryName, subDirectory, symlinkTargetPath)).Dispose();
+            File.CreateSymbolicLink(Path.Join(sourceSubDirectory, "linkToFile"), symlinkTargetPath);
+
+            await TarFile.CreateFromDirectoryAsync(sourceDirectoryName, destinationArchive, includeBaseDirectory: false);
+
+            await using FileStream archiveStream = File.OpenRead(destinationArchive);
+            await TarFile.ExtractToDirectoryAsync(archiveStream, destinationDirectoryName, overwriteFiles: true);
+
+            string destinationSubDirectory = Path.Join(destinationDirectoryName, subDirectory);
+            string symlinkPath = Path.Join(destinationSubDirectory, "linkToFile");
+            Assert.True(File.Exists(symlinkPath));
+
+            FileInfo? fileInfo = new(symlinkPath);
+            Assert.Equal(symlinkTargetPath, fileInfo.LinkTarget);
+
+            FileSystemInfo? symlinkTarget = File.ResolveLinkTarget(symlinkPath, returnFinalTarget: true);
+            Assert.True(File.Exists(symlinkTarget.FullName));
+        }
+
+        [ConditionalTheory(typeof(MountHelper), nameof(MountHelper.CanCreateSymbolicLinks))]
+        [InlineData("../file.txt", null)]
+        [InlineData("../../file.txt", "subDirectory")]
+        public async Task SymlinkRelativeTargets_OutsideTheArchive_Fails_Async(string symlinkTargetPath, string subDirectory)
+        {
+            using TempDirectory root = new TempDirectory();
+
+            string destinationArchive = Path.Join(root.Path, "destination.tar");
+
+            string sourceDirectoryName = Path.Join(root.Path, "baseDirectory");
+            Directory.CreateDirectory(sourceDirectoryName);
+
+            string destinationDirectoryName = Path.Join(root.Path, "destinationDirectory");
+            Directory.CreateDirectory(destinationDirectoryName);
+
+            string sourceSubDirectory = Path.Join(sourceDirectoryName, subDirectory);
+            if (subDirectory != null) Directory.CreateDirectory(sourceSubDirectory);
+
+            File.CreateSymbolicLink(Path.Join(sourceSubDirectory, "linkToFile"), symlinkTargetPath);
+
+            await TarFile.CreateFromDirectoryAsync(sourceDirectoryName, destinationArchive, includeBaseDirectory: false);
+
+            using FileStream archiveStream = File.OpenRead(destinationArchive);
+            Exception exception = await Assert.ThrowsAsync<IOException>(() => TarFile.ExtractToDirectoryAsync(archiveStream, destinationDirectoryName, overwriteFiles: true));
+
+            Assert.Equal(SR.Format(SR.TarExtractingResultsLinkOutside, symlinkTargetPath, destinationDirectoryName), exception.Message);
+        }
+    }
+}