Example #1
0
 public void InvalidPaths_Throw()
 {
     Assert.Throws <ArgumentNullException>(() => TarFile.CreateFromDirectory(sourceDirectoryName: null, destinationFileName: "path", includeBaseDirectory: false));
     Assert.Throws <ArgumentException>(() => TarFile.CreateFromDirectory(sourceDirectoryName: string.Empty, destinationFileName: "path", includeBaseDirectory: false));
     Assert.Throws <ArgumentNullException>(() => TarFile.CreateFromDirectory(sourceDirectoryName: "path", destinationFileName: null, includeBaseDirectory: false));
     Assert.Throws <ArgumentException>(() => TarFile.CreateFromDirectory(sourceDirectoryName: "path", destinationFileName: string.Empty, includeBaseDirectory: false));
 }
Example #2
0
        public void SkipRecursionIntoBaseDirectorySymlink()
        {
            using TempDirectory root = new TempDirectory();

            string destinationArchive = Path.Join(root.Path, "destination.tar");

            string externalDirectory = Path.Join(root.Path, "externalDirectory");

            Directory.CreateDirectory(externalDirectory);

            string subDirectory = Path.Join(externalDirectory, "subDirectory");

            Directory.CreateDirectory(subDirectory);

            string sourceDirectoryName = Path.Join(root.Path, "baseDirectory");

            Directory.CreateSymbolicLink(sourceDirectoryName, externalDirectory);

            TarFile.CreateFromDirectory(sourceDirectoryName, destinationArchive, includeBaseDirectory: true); // Base directory is a symlink, do not recurse

            using FileStream archiveStream = File.OpenRead(destinationArchive);
            using TarReader reader         = new(archiveStream, leaveOpen : false);

            TarEntry entry = reader.GetNextEntry();

            Assert.NotNull(entry);
            Assert.Equal("baseDirectory/", entry.Name);
            Assert.Equal(TarEntryType.SymbolicLink, entry.EntryType);

            Assert.Null(reader.GetNextEntry());
        }
Example #3
0
        public void SkipRecursionIntoDirectorySymlinks()
        {
            using TempDirectory root = new TempDirectory();

            string destinationArchive = Path.Join(root.Path, "destination.tar");

            string externalDirectory = Path.Join(root.Path, "externalDirectory");

            Directory.CreateDirectory(externalDirectory);

            File.Create(Path.Join(externalDirectory, "file.txt")).Dispose();

            string sourceDirectoryName = Path.Join(root.Path, "baseDirectory");

            Directory.CreateDirectory(sourceDirectoryName);

            string subDirectory = Path.Join(sourceDirectoryName, "subDirectory");

            Directory.CreateSymbolicLink(subDirectory, externalDirectory); // Should not recurse here

            TarFile.CreateFromDirectory(sourceDirectoryName, destinationArchive, includeBaseDirectory: false);

            using FileStream archiveStream = File.OpenRead(destinationArchive);
            using TarReader reader         = new(archiveStream, leaveOpen : false);

            TarEntry entry = reader.GetNextEntry();

            Assert.NotNull(entry);
            Assert.Equal("subDirectory/", entry.Name);
            Assert.Equal(TarEntryType.SymbolicLink, entry.EntryType);

            Assert.Null(reader.GetNextEntry()); // file.txt should not be found
        }
Example #4
0
        public void SetsLastModifiedTimeOnExtractedFiles()
        {
            using TempDirectory root = new TempDirectory();

            string inDir  = Path.Join(root.Path, "indir");
            string inFile = Path.Join(inDir, "file");

            string tarFile = Path.Join(root.Path, "file.tar");

            string outDir  = Path.Join(root.Path, "outdir");
            string outFile = Path.Join(outDir, "file");

            Directory.CreateDirectory(inDir);
            File.Create(inFile).Dispose();
            var dt = new DateTime(2001, 1, 2, 3, 4, 5, DateTimeKind.Local);

            File.SetLastWriteTime(inFile, dt);

            TarFile.CreateFromDirectory(sourceDirectoryName: inDir, destinationFileName: tarFile, includeBaseDirectory: false);

            Directory.CreateDirectory(outDir);
            TarFile.ExtractToDirectory(sourceFileName: tarFile, destinationDirectoryName: outDir, overwriteFiles: false);

            Assert.True(File.Exists(outFile));
            Assert.InRange(File.GetLastWriteTime(outFile).Ticks, dt.AddSeconds(-3).Ticks, dt.AddSeconds(3).Ticks); // include some slop for filesystem granularity
        }
Example #5
0
        public void VerifyIncludeBaseDirectory(bool includeBaseDirectory)
        {
            using TempDirectory source      = new TempDirectory();
            using TempDirectory destination = new TempDirectory();

            string fileName1 = "file1.txt";
            string filePath1 = Path.Join(source.Path, fileName1);

            File.Create(filePath1).Dispose();

            string subDirectoryName = "dir/"; // The trailing separator is preserved in the TarEntry.Name
            string subDirectoryPath = Path.Join(source.Path, subDirectoryName);

            Directory.CreateDirectory(subDirectoryPath);

            string fileName2 = "file2.txt";
            string filePath2 = Path.Join(subDirectoryPath, fileName2);

            File.Create(filePath2).Dispose();

            string destinationArchiveFileName = Path.Join(destination.Path, "output.tar");

            TarFile.CreateFromDirectory(source.Path, destinationArchiveFileName, includeBaseDirectory);

            using FileStream fileStream = File.OpenRead(destinationArchiveFileName);
            using TarReader reader      = new TarReader(fileStream);

            List <TarEntry> entries = new List <TarEntry>();

            TarEntry entry;

            while ((entry = reader.GetNextEntry()) != null)
            {
                entries.Add(entry);
            }

            Assert.Equal(3, entries.Count);

            string prefix = includeBaseDirectory ? Path.GetFileName(source.Path) + '/' : string.Empty;

            TarEntry entry1 = entries.FirstOrDefault(x =>
                                                     x.EntryType == TarEntryType.RegularFile &&
                                                     x.Name == prefix + fileName1);

            Assert.NotNull(entry1);

            TarEntry directory = entries.FirstOrDefault(x =>
                                                        x.EntryType == TarEntryType.Directory &&
                                                        x.Name == prefix + subDirectoryName);

            Assert.NotNull(directory);

            string   actualFileName2 = subDirectoryName + fileName2; // Notice the trailing separator in subDirectoryName
            TarEntry entry2          = entries.FirstOrDefault(x =>
                                                              x.EntryType == TarEntryType.RegularFile &&
                                                              x.Name == prefix + actualFileName2);

            Assert.NotNull(entry2);
        }
Example #6
0
        public void NonExistentDirectory_Throws()
        {
            using TempDirectory root = new TempDirectory();
            string dirPath = Path.Join(root.Path, "dir");

            using MemoryStream archive = new MemoryStream();
            Assert.Throws <DirectoryNotFoundException>(() => TarFile.CreateFromDirectory(sourceDirectoryName: dirPath, destination: archive, includeBaseDirectory: false));
        }
Example #7
0
        public void NonExistentDirectory_Throws()
        {
            using TempDirectory root = new TempDirectory();

            string dirPath  = Path.Join(root.Path, "dir");
            string filePath = Path.Join(root.Path, "file.tar");

            Assert.Throws <DirectoryNotFoundException>(() => TarFile.CreateFromDirectory(sourceDirectoryName: "IDontExist", destinationFileName: filePath, includeBaseDirectory: false));
        }
Example #8
0
        public void IncludeAllSegmentsOfPath(bool includeBaseDirectory)
        {
            using TempDirectory source      = new TempDirectory();
            using TempDirectory destination = new TempDirectory();

            string segment1 = Path.Join(source.Path, "segment1");

            Directory.CreateDirectory(segment1);
            string segment2 = Path.Join(segment1, "segment2");

            Directory.CreateDirectory(segment2);
            string textFile = Path.Join(segment2, "file.txt");

            File.Create(textFile).Dispose();

            string destinationArchiveFileName = Path.Join(destination.Path, "output.tar");

            TarFile.CreateFromDirectory(source.Path, destinationArchiveFileName, includeBaseDirectory);

            using FileStream fileStream = File.OpenRead(destinationArchiveFileName);
            using TarReader reader      = new TarReader(fileStream);

            string prefix = includeBaseDirectory ? Path.GetFileName(source.Path) + '/' : string.Empty;

            TarEntry entry;

            if (includeBaseDirectory)
            {
                entry = reader.GetNextEntry();
                Assert.NotNull(entry);
                Assert.Equal(TarEntryType.Directory, entry.EntryType);
                Assert.Equal(prefix, entry.Name);
            }

            entry = reader.GetNextEntry();
            Assert.NotNull(entry);
            Assert.Equal(TarEntryType.Directory, entry.EntryType);
            Assert.Equal(prefix + "segment1/", entry.Name);

            entry = reader.GetNextEntry();
            Assert.NotNull(entry);
            Assert.Equal(TarEntryType.Directory, entry.EntryType);
            Assert.Equal(prefix + "segment1/segment2/", entry.Name);

            entry = reader.GetNextEntry();
            Assert.NotNull(entry);
            Assert.Equal(TarEntryType.RegularFile, entry.EntryType);
            Assert.Equal(prefix + "segment1/segment2/file.txt", entry.Name);

            Assert.Null(reader.GetNextEntry());
        }
Example #9
0
        public void DestinationExists_Throws()
        {
            using TempDirectory root = new TempDirectory();

            string dirPath = Path.Join(root.Path, "dir");

            Directory.CreateDirectory(dirPath);

            string filePath = Path.Join(root.Path, "file.tar");

            File.Create(filePath).Dispose();

            Assert.Throws <IOException>(() => TarFile.CreateFromDirectory(sourceDirectoryName: dirPath, destinationFileName: filePath, includeBaseDirectory: false));
        }
Example #10
0
        public void IncludeBaseDirectoryIfEmpty()
        {
            using TempDirectory source      = new TempDirectory();
            using TempDirectory destination = new TempDirectory();

            string destinationArchiveFileName = Path.Join(destination.Path, "output.tar");

            TarFile.CreateFromDirectory(source.Path, destinationArchiveFileName, includeBaseDirectory: true);

            using FileStream fileStream = File.OpenRead(destinationArchiveFileName);
            using (TarReader reader = new TarReader(fileStream))
            {
                TarEntry entry = reader.GetNextEntry();
                Assert.NotNull(entry);
                Assert.Equal(TarEntryType.Directory, entry.EntryType);
                Assert.Equal(Path.GetFileName(source.Path) + '/', entry.Name);

                Assert.Null(reader.GetNextEntry());
            }
        }
Example #11
0
        public void TarGz_TarFile_CreateFromDir_ExtractToDir()
        {
            using TempDirectory root = new TempDirectory();

            string archivePath = Path.Join(root.Path, "compressed.tar.gz");

            string sourceDirectory = Path.Join(root.Path, "source");

            Directory.CreateDirectory(sourceDirectory);

            string destinationDirectory = Path.Join(root.Path, "destination");

            Directory.CreateDirectory(destinationDirectory);

            string fileName = "file.txt";
            string filePath = Path.Join(sourceDirectory, fileName);

            File.Create(filePath).Dispose();

            using (FileStream streamToCompress = File.Create(archivePath))
            {
                using GZipStream compressorStream = new GZipStream(streamToCompress, CompressionMode.Compress);
                TarFile.CreateFromDirectory(sourceDirectory, compressorStream, includeBaseDirectory: false);
            }
            FileInfo fileInfo = new FileInfo(archivePath);

            Assert.True(fileInfo.Exists);
            Assert.True(fileInfo.Length > 0);

            using (FileStream streamToDecompress = File.OpenRead(archivePath))
            {
                using GZipStream decompressorStream = new GZipStream(streamToDecompress, CompressionMode.Decompress);
                TarFile.ExtractToDirectory(decompressorStream, destinationDirectory, overwriteFiles: true);
                Assert.True(File.Exists(filePath));
            }
        }
Example #12
0
 public void UnwritableStream_Throws()
 {
     using MemoryStream archive     = new MemoryStream();
     using WrappedStream unwritable = new WrappedStream(archive, canRead: true, canWrite: false, canSeek: true);
     Assert.Throws <IOException>(() => TarFile.CreateFromDirectory(sourceDirectoryName: "path", destination: unwritable, includeBaseDirectory: false));
 }
Example #13
0
 public void NullStream_Throws()
 {
     using MemoryStream archive = new MemoryStream();
     Assert.Throws <ArgumentNullException>(() => TarFile.CreateFromDirectory(sourceDirectoryName: "path", destination: null, includeBaseDirectory: false));
 }
Example #14
0
 public void InvalidPath_Throws()
 {
     using MemoryStream archive = new MemoryStream();
     Assert.Throws <ArgumentNullException>(() => TarFile.CreateFromDirectory(sourceDirectoryName: null, destination: archive, includeBaseDirectory: false));
     Assert.Throws <ArgumentException>(() => TarFile.CreateFromDirectory(sourceDirectoryName: string.Empty, destination: archive, includeBaseDirectory: false));
 }
Example #15
0
        public async Task VerifyIncludeBaseDirectory_Async(bool includeBaseDirectory)
        {
            using TempDirectory source      = new TempDirectory();
            using TempDirectory destination = new TempDirectory();

            UnixFileMode baseDirectoryMode = TestPermission1;

            SetUnixFileMode(source.Path, baseDirectoryMode);

            string fileName1 = "file1.txt";
            string filePath1 = Path.Join(source.Path, fileName1);

            File.Create(filePath1).Dispose();
            UnixFileMode filename1Mode = TestPermission2;

            SetUnixFileMode(filePath1, filename1Mode);

            string subDirectoryName = "dir/"; // The trailing separator is preserved in the TarEntry.Name
            string subDirectoryPath = Path.Join(source.Path, subDirectoryName);

            Directory.CreateDirectory(subDirectoryPath);
            UnixFileMode subDirectoryMode = TestPermission3;

            SetUnixFileMode(subDirectoryPath, subDirectoryMode);

            string fileName2 = "file2.txt";
            string filePath2 = Path.Join(subDirectoryPath, fileName2);

            File.Create(filePath2).Dispose();
            UnixFileMode filename2Mode = TestPermission4;

            SetUnixFileMode(filePath2, filename2Mode);

            string destinationArchiveFileName = Path.Join(destination.Path, "output.tar");

            TarFile.CreateFromDirectory(source.Path, destinationArchiveFileName, includeBaseDirectory);

            List <TarEntry> entries = new List <TarEntry>();

            FileStreamOptions readOptions = new()
            {
                Access  = FileAccess.Read,
                Mode    = FileMode.Open,
                Options = FileOptions.Asynchronous,
            };

            await using (FileStream fileStream = File.Open(destinationArchiveFileName, readOptions))
            {
                await using (TarReader reader = new TarReader(fileStream))
                {
                    TarEntry entry;
                    while ((entry = await reader.GetNextEntryAsync()) != null)
                    {
                        entries.Add(entry);
                    }
                }
            }

            int expectedCount = 3 + (includeBaseDirectory ? 1 : 0);

            Assert.Equal(expectedCount, entries.Count);

            string prefix = includeBaseDirectory ? Path.GetFileName(source.Path) + '/' : string.Empty;

            if (includeBaseDirectory)
            {
                TarEntry baseEntry = entries.FirstOrDefault(x =>
                                                            x.EntryType == TarEntryType.Directory &&
                                                            x.Name == prefix);
                Assert.NotNull(baseEntry);
                AssertEntryModeFromFileSystemEquals(baseEntry, baseDirectoryMode);
            }

            TarEntry entry1 = entries.FirstOrDefault(x =>
                                                     x.EntryType == TarEntryType.RegularFile &&
                                                     x.Name == prefix + fileName1);

            Assert.NotNull(entry1);
            AssertEntryModeFromFileSystemEquals(entry1, filename1Mode);

            TarEntry directory = entries.FirstOrDefault(x =>
                                                        x.EntryType == TarEntryType.Directory &&
                                                        x.Name == prefix + subDirectoryName);

            Assert.NotNull(directory);
            AssertEntryModeFromFileSystemEquals(directory, subDirectoryMode);

            string   actualFileName2 = subDirectoryName + fileName2; // Notice the trailing separator in subDirectoryName
            TarEntry entry2          = entries.FirstOrDefault(x =>
                                                              x.EntryType == TarEntryType.RegularFile &&
                                                              x.Name == prefix + actualFileName2);

            Assert.NotNull(entry2);
            AssertEntryModeFromFileSystemEquals(entry2, filename2Mode);
        }